[pypy-svn] r65577 - in pypy/branch/pyjitpl5-experiments/pypy: jit/backend/x86 jit/backend/x86/test rpython/lltypesystem rpython/memory/gctransform
arigo at codespeak.net
arigo at codespeak.net
Thu Jun 4 15:51:20 CEST 2009
Author: arigo
Date: Thu Jun 4 15:51:20 2009
New Revision: 65577
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/assembler.py
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/gc.py
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/regalloc.py
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/runner.py
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/test/test_zrpy_gc.py
pypy/branch/pyjitpl5-experiments/pypy/rpython/lltypesystem/lloperation.py
pypy/branch/pyjitpl5-experiments/pypy/rpython/memory/gctransform/framework.py
Log:
Allow allocation of strings and unicodes with the framework GC in the JIT.
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/assembler.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/assembler.py Thu Jun 4 15:51:20 2009
@@ -92,6 +92,8 @@
self.verbose = False
self.rtyper = cpu.rtyper
self.malloc_func_addr = 0
+ self.malloc_str_func_addr = 0
+ self.malloc_unicode_func_addr = 0
self._exception_data = lltype.nullptr(rffi.CArray(lltype.Signed))
self._exception_addr = 0
self.mcstack = MachineCodeStack()
@@ -125,16 +127,25 @@
self.mc = self.mcstack.next_mc()
self.mc2 = self.mcstack.next_mc()
# the address of the function called by 'new'
- ll_new = self.cpu.gc_ll_descr.get_funcptr_for_new()
+ gc_ll_descr = self.cpu.gc_ll_descr
+ ll_new = gc_ll_descr.get_funcptr_for_new()
self.malloc_func_addr = rffi.cast(lltype.Signed, ll_new)
+ if gc_ll_descr.get_funcptr_for_newstr is not None:
+ ll_new_str = gc_ll_descr.get_funcptr_for_newstr()
+ self.malloc_str_func_addr = rffi.cast(lltype.Signed,
+ ll_new_str)
+ if gc_ll_descr.get_funcptr_for_newunicode is not None:
+ ll_new_unicode = gc_ll_descr.get_funcptr_for_newunicode()
+ self.malloc_unicode_func_addr = rffi.cast(lltype.Signed,
+ ll_new_unicode)
# for moving GCs, the array used to hold the address of GC objects
# that appear as ConstPtr.
- if self.cpu.gc_ll_descr.moving_gc:
- self.gcrefs = self.cpu.gc_ll_descr.GcRefList()
+ if gc_ll_descr.moving_gc:
+ self.gcrefs = gc_ll_descr.GcRefList()
self.single_gcref_descr = ConstDescr3(0, WORD, True)
else:
self.gcrefs = None
- self.gcrootmap = self.cpu.gc_ll_descr.gcrootmap
+ self.gcrootmap = gc_ll_descr.gcrootmap
if self.gcrootmap:
self.gcrootmap.initialize()
@@ -316,7 +327,7 @@
assert not isinstance(arg, MODRM)
self.mc.PUSH(arg)
self.mc.CALL(rel32(addr))
- self.mark_gc_roots(len(args))
+ self.mark_gc_roots()
self.mc.ADD(esp, imm(len(args) * WORD))
assert res is eax
@@ -466,6 +477,14 @@
assert result_loc is eax
self.call(self.malloc_func_addr, arglocs, eax)
+ def genop_newstr(self, op, arglocs, result_loc):
+ assert result_loc is eax
+ self.call(self.malloc_str_func_addr, arglocs, eax)
+
+ def genop_newunicode(self, op, arglocs, result_loc):
+ assert result_loc is eax
+ self.call(self.malloc_unicode_func_addr, arglocs, eax)
+
def genop_getfield_gc(self, op, arglocs, resloc):
base_loc, ofs_loc, size_loc = arglocs
assert isinstance(size_loc, IMM32)
@@ -758,7 +777,7 @@
if isinstance(x, MODRM):
x = stack_pos(x.position)
self.mc.CALL(x)
- self.mark_gc_roots(extra_on_stack)
+ self.mark_gc_roots()
self.mc.ADD(esp, imm(WORD * extra_on_stack))
if size == 1:
self.mc.AND(eax, imm(0xff))
@@ -788,7 +807,7 @@
# self.gen_call(op, arglocs, resloc)
# self.mc.MOVZX(eax, eax)
- def mark_gc_roots(self, extra_on_stack):
+ def mark_gc_roots(self):
if self.gcrootmap:
gclocs = []
regalloc = self._regalloc
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/gc.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/gc.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/gc.py Thu Jun 4 15:51:20 2009
@@ -1,5 +1,5 @@
from pypy.rlib import rgc
-from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rclass
+from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rclass, rstr
from pypy.rpython.lltypesystem.lloperation import llop
from pypy.rpython.annlowlevel import llhelper
from pypy.translator.tool.cbuild import ExternalCompilationInfo
@@ -7,6 +7,7 @@
from pypy.jit.backend.x86.runner import ConstDescr3
from pypy.jit.backend.x86.ri386 import MODRM, IMM32, mem, imm32, rel32, heap
from pypy.jit.backend.x86.ri386 import REG, eax, ecx, edx
+from pypy.jit.backend.x86.assembler import WORD
# ____________________________________________________________
@@ -51,7 +52,26 @@
basesize = arraydescr.v0
itemsize = arraydescr.v1
size = basesize + itemsize * num_elem
- return self.funcptr_for_new(size)
+ res = self.funcptr_for_new(size)
+ rffi.cast(rffi.CArrayPtr(lltype.Signed), res)[0] = num_elem
+ return res
+
+ def gc_malloc_str(self, num_elem, translate_support_code):
+ basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR,
+ translate_support_code)
+ assert itemsize == 1
+ size = basesize + num_elem
+ res = self.funcptr_for_new(size)
+ rffi.cast(rffi.CArrayPtr(lltype.Signed), res)[ofs_length/WORD] = num_elem
+ return res
+
+ def gc_malloc_unicode(self, num_elem, translate_support_code):
+ basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE,
+ translate_support_code)
+ size = basesize + num_elem * itemsize
+ res = self.funcptr_for_new(size)
+ rffi.cast(rffi.CArrayPtr(lltype.Signed), res)[ofs_length/WORD] = num_elem
+ return res
def args_for_new(self, descrsize):
assert isinstance(descrsize, ConstDescr3)
@@ -61,6 +81,9 @@
def get_funcptr_for_new(self):
return self.funcptr_for_new
+ get_funcptr_for_newstr = None
+ get_funcptr_for_newunicode = None
+
# ____________________________________________________________
class GcRefList:
@@ -271,6 +294,28 @@
[lltype.Signed, lltype.Signed, lltype.Bool], llmemory.GCREF))
self.WB_FUNCPTR = lltype.Ptr(lltype.FuncType(
[llmemory.Address, llmemory.Address], lltype.Void))
+ #
+ (str_basesize, str_itemsize, str_ofs_length
+ ) = symbolic.get_array_token(rstr.STR, True)
+ (unicode_basesize, unicode_itemsize, unicode_ofs_length
+ ) = symbolic.get_array_token(rstr.UNICODE, True)
+ str_type_id = self.layoutbuilder.get_type_id(rstr.STR)
+ unicode_type_id = self.layoutbuilder.get_type_id(rstr.UNICODE)
+ #
+ def malloc_str(length):
+ return llop.do_malloc_varsize_clear(
+ llmemory.GCREF,
+ str_type_id, length, str_basesize, str_itemsize,
+ str_ofs_length, True, False)
+ def malloc_unicode(length):
+ return llop.do_malloc_varsize_clear(
+ llmemory.GCREF,
+ unicode_type_id, length, unicode_basesize, unicode_itemsize,
+ unicode_ofs_length, True, False)
+ self.malloc_str = malloc_str
+ self.malloc_unicode = malloc_unicode
+ self.GC_MALLOC_STR_UNICODE = lltype.Ptr(lltype.FuncType(
+ [lltype.Signed], llmemory.GCREF))
def sizeof(self, S, translate_support_code):
from pypy.rpython.memory.gctypelayout import weakpointer_offset
@@ -292,6 +337,14 @@
def gc_malloc_array(self, arraydescr, num_elem):
raise NotImplementedError
+ def gc_malloc_str(self, num_elem, translate_support_code):
+ assert translate_support_code, "required with the framework GC"
+ return self.malloc_str(num_elem)
+
+ def gc_malloc_unicode(self, num_elem, translate_support_code):
+ assert translate_support_code, "required with the framework GC"
+ return self.malloc_unicode(num_elem)
+
def args_for_new(self, descrsize):
assert isinstance(descrsize, ConstDescr3)
size = descrsize.v0
@@ -302,6 +355,12 @@
def get_funcptr_for_new(self):
return llhelper(self.GC_MALLOC_BASIC, self.malloc_basic)
+ def get_funcptr_for_newstr(self):
+ return llhelper(self.GC_MALLOC_STR_UNICODE, self.malloc_str)
+
+ def get_funcptr_for_newunicode(self):
+ return llhelper(self.GC_MALLOC_STR_UNICODE, self.malloc_unicode)
+
def do_write_barrier(self, gcref_struct, gcref_newptr):
hdr_addr = llmemory.cast_ptr_to_adr(gcref_struct)
hdr = llmemory.cast_adr_to_ptr(hdr_addr, self.HDRPTR)
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/regalloc.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/regalloc.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/regalloc.py Thu Jun 4 15:51:20 2009
@@ -952,23 +952,35 @@
return self._call(op, arglocs)
def consider_newstr(self, op, ignored):
+ gc_ll_descr = self.assembler.cpu.gc_ll_descr
+ if gc_ll_descr.get_funcptr_for_newstr is not None:
+ # framework GC
+ loc = self.loc(op.args[0])
+ return self._call(op, [loc])
+ # boehm GC (XXX kill the following code at some point)
ofs_items, itemsize, ofs = symbolic.get_array_token(rstr.STR, self.translate_support_code)
assert itemsize == 1
- return self._malloc_varsize(0, ofs_items, ofs, 0, op.args[0],
+ return self._malloc_varsize(ofs_items, ofs, 0, op.args[0],
op.result)
def consider_newunicode(self, op, ignored):
+ gc_ll_descr = self.assembler.cpu.gc_ll_descr
+ if gc_ll_descr.get_funcptr_for_newunicode is not None:
+ # framework GC
+ loc = self.loc(op.args[0])
+ return self._call(op, [loc])
+ # boehm GC (XXX kill the following code at some point)
ofs_items, itemsize, ofs = symbolic.get_array_token(rstr.UNICODE, self.translate_support_code)
if itemsize == 4:
- return self._malloc_varsize(0, ofs_items, ofs, 2, op.args[0],
+ return self._malloc_varsize(ofs_items, ofs, 2, op.args[0],
op.result)
elif itemsize == 2:
- return self._malloc_varsize(0, ofs_items, ofs, 1, op.args[0],
+ return self._malloc_varsize(ofs_items, ofs, 1, op.args[0],
op.result)
else:
assert False, itemsize
- def _malloc_varsize(self, ofs, ofs_items, ofs_length, size, v, res_v):
+ def _malloc_varsize(self, ofs_items, ofs_length, size, v, res_v):
if isinstance(v, Box):
loc = self.make_sure_var_in_reg(v, [v])
self.sync_var(v)
@@ -978,9 +990,9 @@
self.Perform(ResOperation(rop.INT_MUL, [], None),
[loc, imm(1 << size)], loc)
self.Perform(ResOperation(rop.INT_ADD, [], None),
- [loc, imm(ofs + ofs_items)], loc)
+ [loc, imm(ofs_items)], loc)
else:
- loc = imm(ofs + ofs_items + (v.getint() << size))
+ loc = imm(ofs_items + (v.getint() << size))
self._call(ResOperation(rop.NEW, [v], res_v),
[loc], [v])
loc = self.make_sure_var_in_reg(v, [res_v])
@@ -988,11 +1000,11 @@
# now we have to reload length to some reasonable place
self.eventually_free_var(v)
self.PerformDiscard(ResOperation(rop.SETFIELD_GC, [], None),
- [eax, imm(ofs + ofs_length), imm(WORD), loc])
+ [eax, imm(ofs_length), imm(WORD), loc])
def consider_new_array(self, op, ignored):
size_of_field, basesize, _ = self._unpack_arraydescr(op.descr)
- return self._malloc_varsize(0, basesize, 0, size_of_field, op.args[0],
+ return self._malloc_varsize(basesize, 0, size_of_field, op.args[0],
op.result)
def _unpack_arraydescr(self, arraydescr):
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/runner.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/runner.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/runner.py Thu Jun 4 15:51:20 2009
@@ -538,22 +538,19 @@
def do_new_array(self, args, arraydescr):
num_elem = args[0].getint()
res = self.gc_ll_descr.gc_malloc_array(arraydescr, num_elem)
- rffi.cast(rffi.CArrayPtr(lltype.Signed), res)[0] = num_elem
- # XXX don't use 0 above!
return BoxPtr(self.cast_adr_to_gcref(res))
- def _new_do_newstr(TP):
- def do_newstr(self, args, descr=0):
- basesize, itemsize, ofs_length = symbolic.get_array_token(TP,
- self.translate_support_code)
- num_elem = args[0].getint()
- size = basesize + num_elem * itemsize
- res = self.gc_ll_descr.funcptr_for_new(size) # XXX don't use
- rffi.cast(rffi.CArrayPtr(lltype.Signed), res)[ofs_length/WORD] = num_elem
- return BoxPtr(self.cast_adr_to_gcref(res))
- return do_newstr
- do_newstr = _new_do_newstr(rstr.STR)
- do_newunicode = _new_do_newstr(rstr.UNICODE)
+ def do_newstr(self, args, descr=0):
+ num_elem = args[0].getint()
+ tsc = self.translate_support_code
+ res = self.gc_ll_descr.gc_malloc_str(num_elem, tsc)
+ return BoxPtr(self.cast_adr_to_gcref(res))
+
+ def do_newunicode(self, args, descr=0):
+ num_elem = args[0].getint()
+ tsc = self.translate_support_code
+ res = self.gc_ll_descr.gc_malloc_unicode(num_elem, tsc)
+ return BoxPtr(self.cast_adr_to_gcref(res))
def do_strsetitem(self, args, descr=0):
basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR,
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/test/test_zrpy_gc.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/test/test_zrpy_gc.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/test/test_zrpy_gc.py Thu Jun 4 15:51:20 2009
@@ -207,3 +207,18 @@
res = compile_and_run(get_test(main), "hybrid", gcrootfinder="asmgcc",
jit=True)
assert int(res) == 20
+
+def test_compile_hybrid_5():
+ # Test string manipulation.
+ myjitdriver = JitDriver(greens = [], reds = ['n', 'x', 's'])
+ def main(n, x):
+ s = ''
+ while n > 0:
+ myjitdriver.can_enter_jit(n=n, x=x, s=s)
+ myjitdriver.jit_merge_point(n=n, x=x, s=s)
+ n -= x.foo
+ s += str(n)
+ assert len(s) == 1*5 + 2*45 + 3*450 + 4*500
+ res = compile_and_run(get_test(main), "hybrid", gcrootfinder="asmgcc",
+ jit=True)
+ assert int(res) == 20
Modified: pypy/branch/pyjitpl5-experiments/pypy/rpython/lltypesystem/lloperation.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/rpython/lltypesystem/lloperation.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/rpython/lltypesystem/lloperation.py Thu Jun 4 15:51:20 2009
@@ -388,6 +388,7 @@
'get_exception_addr': LLOp(),
'get_exc_value_addr': LLOp(),
'do_malloc_fixedsize_clear': LLOp(),
+ 'do_malloc_varsize_clear': LLOp(),
'get_write_barrier_failing_case': LLOp(sideeffects=False),
# __________ GC operations __________
Modified: pypy/branch/pyjitpl5-experiments/pypy/rpython/memory/gctransform/framework.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/rpython/memory/gctransform/framework.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/rpython/memory/gctransform/framework.py Thu Jun 4 15:51:20 2009
@@ -617,6 +617,17 @@
v_has_finalizer, v_contains_weakptr],
resultvar=op.result)
+ def gct_do_malloc_varsize_clear(self, hop):
+ # used by the JIT (see the x86 backend)
+ op = hop.spaceop
+ [v_typeid, v_length, v_size, v_itemsize,
+ v_offset_to_length, v_can_collect, v_has_finalizer] = op.args
+ hop.genop("direct_call",
+ [self.malloc_varsize_clear_ptr, self.c_const_gc,
+ v_typeid, v_length, v_size, v_itemsize,
+ v_offset_to_length, v_can_collect, v_has_finalizer],
+ resultvar=op.result)
+
def gct_get_write_barrier_failing_case(self, hop):
op = hop.spaceop
hop.genop("same_as",
More information about the Pypy-commit
mailing list