[pypy-svn] r64743 - in pypy/branch/pyjitpl5/pypy/jit/backend/minimal: . test
antocuni at codespeak.net
antocuni at codespeak.net
Mon Apr 27 19:12:02 CEST 2009
Author: antocuni
Date: Mon Apr 27 19:12:02 2009
New Revision: 64743
Modified:
pypy/branch/pyjitpl5/pypy/jit/backend/minimal/runner.py
pypy/branch/pyjitpl5/pypy/jit/backend/minimal/support.py
pypy/branch/pyjitpl5/pypy/jit/backend/minimal/test/test_basic.py
pypy/branch/pyjitpl5/pypy/jit/backend/minimal/test/test_runner.py
pypy/branch/pyjitpl5/pypy/jit/backend/minimal/test/test_zrpy_exception.py
Log:
split the minimal backend into an ootype and lltype version
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/minimal/runner.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/minimal/runner.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/minimal/runner.py Mon Apr 27 19:12:02 2009
@@ -2,22 +2,40 @@
from pypy.rlib.objectmodel import specialize, we_are_translated
from pypy.rlib.debug import ll_assert, debug_print
from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rstr, rclass
+from pypy.rpython.ootypesystem import ootype
from pypy.jit.metainterp.history import AbstractDescr, Box, BoxInt, BoxPtr
+from pypy.jit.metainterp.history import BoxObj
from pypy.jit.metainterp import executor
from pypy.jit.metainterp.resoperation import rop, opname
+from pypy.jit.backend import model
DEBUG = False
-class CPU(object):
- is_oo = False # XXX for now
+def cached_method(cachename):
+ def decorate(func):
+ def cached_func(self, *args):
+ try:
+ return getattr(self, cachename)[args]
+ except (KeyError, AttributeError):
+ descr = func(self, *args)
+ if not hasattr(self, cachename):
+ setattr(self, cachename, {})
+ getattr(self, cachename)[args] = descr
+ return descr
+ return cached_func
+ return decorate
+
+
+class BaseCPU(model.AbstractCPU):
def __init__(self, rtyper, stats, translate_support_code=False,
mixlevelann=None):
self.rtyper = rtyper
- if rtyper is not None:
- self.is_oo = rtyper.type_system.name == "ootypesystem"
- else:
- self.is_oo = False
+ if rtyper:
+ if self.is_oo:
+ assert rtyper.type_system.name == "ootypesystem"
+ else:
+ assert rtyper.type_system.name == "lltypesystem"
self.stats = stats
self.translate_support_code = translate_support_code
self._future_values = []
@@ -132,6 +150,10 @@
op, env = self.latest_fail
return env[op.args[index]].getptr_base()
+ def get_latest_value_obj(self, index):
+ op, env = self.latest_fail
+ return env[op.args[index]].getobj()
+
def execute_guard(self, opnum, argboxes):
if opnum == rop.GUARD_TRUE:
value = argboxes[0].getint()
@@ -172,94 +194,45 @@
# ----------
- def cached_method(cachename):
- def decorate(func):
- def cached_func(self, *args):
- try:
- return getattr(self, cachename)[args]
- except (KeyError, AttributeError):
- descr = func(self, *args)
- if not hasattr(self, cachename):
- setattr(self, cachename, {})
- getattr(self, cachename)[args] = descr
- return descr
- return cached_func
- return decorate
-
- @cached_method('_sizecache')
- def sizeof(self, TYPE):
- def alloc():
- p = lltype.malloc(TYPE)
- return lltype.cast_opaque_ptr(llmemory.GCREF, p)
- return SizeDescr(alloc)
-
@cached_method('_fieldcache')
- def fielddescrof(self, STRUCT, name):
+ def fielddescrof(self, T, name):
+ TYPE, FIELDTYPE, reveal = self._get_field(T, name)
dict2 = base_dict.copy()
- dict2['PTR'] = lltype.Ptr(STRUCT)
- FIELDTYPE = getattr(STRUCT, name)
+ dict2['TYPE'] = TYPE
+ dict2['reveal'] = reveal
dict = {'name': name,
'input': make_reader(FIELDTYPE, 'xbox', dict2),
- 'result': make_writer(FIELDTYPE, 'x', dict2)}
+ 'result': make_writer(FIELDTYPE, 'x', dict2),}
exec py.code.Source("""
def getfield(cpu, pbox):
- p = reveal_ptr(cpu, PTR, pbox)
+ p = reveal(cpu, TYPE, pbox)
x = getattr(p, %(name)r)
return %(result)s
def setfield(cpu, pbox, xbox):
- p = reveal_ptr(cpu, PTR, pbox)
+ p = reveal(cpu, TYPE, pbox)
x = %(input)s
setattr(p, %(name)r, x)
""" % dict).compile() in dict2
- sort_key = _count_sort_key(STRUCT, name)
+ sort_key = self._count_sort_key(T, name)
return FieldDescr(dict2['getfield'], dict2['setfield'], sort_key)
- @cached_method('_arraycache')
- def arraydescrof(self, ARRAY):
- dict2 = base_dict.copy()
- dict2['malloc'] = lltype.malloc
- dict2['ARRAY'] = ARRAY
- dict2['PTR'] = lltype.Ptr(ARRAY)
- dict = {'input': make_reader(ARRAY.OF, 'xbox', dict2),
- 'result': make_writer(ARRAY.OF, 'x', dict2)}
- exec py.code.Source("""
- def new(length):
- p = malloc(ARRAY, length)
- return cast_opaque_ptr(GCREF, p)
- def length(cpu, pbox):
- p = reveal_ptr(cpu, PTR, pbox)
- return len(p)
- def getarrayitem(cpu, pbox, index):
- p = reveal_ptr(cpu, PTR, pbox)
- x = p[index]
- return %(result)s
- def setarrayitem(cpu, pbox, index, xbox):
- p = reveal_ptr(cpu, PTR, pbox)
- x = %(input)s
- p[index] = x
- """ % dict).compile() in dict2
- return ArrayDescr(dict2['new'],
- dict2['length'],
- dict2['getarrayitem'],
- dict2['setarrayitem'])
-
@cached_method('_callcache')
def calldescrof(self, FUNC, ARGS, RESULT):
+ FUNC, cast_func = self._get_cast_func(ARGS, RESULT)
dict2 = base_dict.copy()
args = []
for i, ARG in enumerate(ARGS):
args.append(make_reader(ARG, 'args[%d]' % i, dict2))
dict = {'args': ', '.join(args),
'result': make_writer(RESULT, 'res', dict2)}
- dict2.update({'rffi': rffi,
- 'FUNC': lltype.Ptr(lltype.FuncType(ARGS, RESULT)),
+ dict2.update({'cast_func': cast_func,
'length': len(ARGS),
'll_assert': ll_assert,
})
exec py.code.Source("""
def call(cpu, function, args):
ll_assert(len(args) == length, 'call: wrong arg count')
- function = rffi.cast(FUNC, function)
+ function = cast_func(function)
res = function(%(args)s)
return %(result)s
""" % dict).compile() in dict2
@@ -269,7 +242,7 @@
errbox = BoxPtr()
else:
errbox = BoxInt()
- return CallDescr(dict2['FUNC'], dict2['call'], errbox)
+ return CallDescr(FUNC, dict2['call'], errbox)
# ----------
@@ -279,15 +252,6 @@
p = sizedescr.alloc()
return BoxPtr(p)
- def do_new_with_vtable(self, args, sizedescr):
- assert isinstance(sizedescr, SizeDescr)
- assert sizedescr.alloc is not None
- p = sizedescr.alloc()
- classadr = args[0].getaddr(self)
- pobj = lltype.cast_opaque_ptr(rclass.OBJECTPTR, p)
- pobj.typeptr = llmemory.cast_adr_to_ptr(classadr, rclass.CLASSTYPE)
- return BoxPtr(p)
-
def do_getfield_gc(self, args, fielddescr):
assert isinstance(fielddescr, FieldDescr)
assert fielddescr.getfield is not None
@@ -433,6 +397,110 @@
return rffi.cast(TYPE, x)
+class LLtypeCPU(BaseCPU):
+ is_oo = False
+
+ def _get_field(self, STRUCT, name):
+ PTR = lltype.Ptr(STRUCT)
+ FIELDTYPE = getattr(STRUCT, name)
+ return PTR, FIELDTYPE, reveal_ptr
+
+ def _get_cast_func(self, ARGS, RESULT):
+ FUNC = lltype.Ptr(lltype.FuncType(ARGS, RESULT))
+ def cast_func(function):
+ return rffi.cast(FUNC, function)
+ return FUNC, cast_func
+
+ def _count_sort_key(self, STRUCT, name):
+ i = list(STRUCT._names).index(name)
+ while True:
+ _, STRUCT = STRUCT._first_struct()
+ if not STRUCT:
+ break
+ i += len(STRUCT._names) + 1
+ return i
+
+ @cached_method('_sizecache')
+ def sizeof(self, TYPE):
+ def alloc():
+ p = lltype.malloc(TYPE)
+ return lltype.cast_opaque_ptr(llmemory.GCREF, p)
+ return SizeDescr(alloc)
+
+ @cached_method('_arraycache')
+ def arraydescrof(self, ARRAY):
+ dict2 = base_dict.copy()
+ dict2['malloc'] = lltype.malloc
+ dict2['ARRAY'] = ARRAY
+ dict2['PTR'] = lltype.Ptr(ARRAY)
+ dict = {'input': make_reader(ARRAY.OF, 'xbox', dict2),
+ 'result': make_writer(ARRAY.OF, 'x', dict2)}
+ exec py.code.Source("""
+ def new(length):
+ p = malloc(ARRAY, length)
+ return cast_opaque_ptr(GCREF, p)
+ def length(cpu, pbox):
+ p = reveal_ptr(cpu, PTR, pbox)
+ return len(p)
+ def getarrayitem(cpu, pbox, index):
+ p = reveal_ptr(cpu, PTR, pbox)
+ x = p[index]
+ return %(result)s
+ def setarrayitem(cpu, pbox, index, xbox):
+ p = reveal_ptr(cpu, PTR, pbox)
+ x = %(input)s
+ p[index] = x
+ """ % dict).compile() in dict2
+ return ArrayDescr(dict2['new'],
+ dict2['length'],
+ dict2['getarrayitem'],
+ dict2['setarrayitem'])
+
+ def do_new_with_vtable(self, args, sizedescr):
+ assert isinstance(sizedescr, SizeDescr)
+ assert sizedescr.alloc is not None
+ p = sizedescr.alloc()
+ classadr = args[0].getaddr(self)
+ pobj = lltype.cast_opaque_ptr(rclass.OBJECTPTR, p)
+ pobj.typeptr = llmemory.cast_adr_to_ptr(classadr, rclass.CLASSTYPE)
+ return BoxPtr(p)
+
+
+class OOtypeCPU(BaseCPU):
+ is_oo = True
+
+ def _get_field(self, TYPE, name):
+ _, FIELDTYPE = TYPE._lookup_field(name)
+ return TYPE, FIELDTYPE, reveal_obj
+
+ def _get_cast_func(self, ARGS, RESULT):
+ FUNC = ootype.StaticMethod(ARGS, RESULT)
+ def cast_func(function):
+ return ootype.cast_from_object(FUNC, function)
+ return FUNC, cast_func
+
+ def _count_sort_key(self, INSTANCE, name):
+ fields = sorted(INSTANCE._allfields().keys())
+ return fields.index(name)
+
+ @cached_method('_typedescrcache')
+ def typedescrof(self, TYPE):
+ def alloc():
+ obj = ootype.new(TYPE)
+ return ootype.cast_to_object(obj)
+ return SizeDescr(alloc)
+
+ @cached_method('_methdescrcache')
+ def methdescrof(self, SELFTYPE, methname):
+ return MethDescr(SELFTYPE, methname)
+
+ def do_new_with_vtable(self, args, sizedescr):
+ assert isinstance(sizedescr, SizeDescr)
+ assert sizedescr.alloc is not None
+ obj = sizedescr.alloc()
+ return BoxObj(obj)
+
+
class SizeDescr(AbstractDescr):
alloc = None
def __init__(self, alloc):
@@ -468,6 +536,11 @@
self.call = call
self.errbox = errbox
+class MethDescr(AbstractDescr):
+
+ def __init__(self, SELFTYPE, methname):
+ pass
+
# ____________________________________________________________
@@ -485,6 +558,8 @@
else:
return "cast_adr_to_ptr(%s.getaddr(cpu), %s)" % (boxstr,
_name(dict, TYPE))
+ elif isinstance(TYPE, ootype.OOType):
+ return "ootype.cast_from_object(%s, %s.getobj())" % (_name(dict, TYPE), boxstr)
else:
return "cast_primitive(%s, %s.getint())" % (_name(dict, TYPE), boxstr)
@@ -496,17 +571,11 @@
return "BoxPtr(cast_opaque_ptr(GCREF, %s))" % (str,)
else:
return "BoxInt(rffi.cast(Signed, %s))" % (str,)
+ elif isinstance(TYPE, ootype.OOType):
+ return "BoxObj(ootype.cast_to_object(%s))" % (str,)
else:
return "BoxInt(cast_primitive(Signed, %s))" % (str,)
-def _count_sort_key(STRUCT, name):
- i = list(STRUCT._names).index(name)
- while True:
- _, STRUCT = STRUCT._first_struct()
- if not STRUCT:
- return i
- i += len(STRUCT._names) + 1
-
@specialize.arg(1)
def reveal_ptr(cpu, PTR, box):
if PTR.TO._gckind == 'gc':
@@ -515,11 +584,20 @@
adr = box.getaddr(cpu)
return llmemory.cast_adr_to_ptr(adr, PTR)
+ at specialize.arg(1)
+def reveal_obj(cpu, TYPE, box):
+ if isinstance(TYPE, ootype.OOType):
+ return ootype.cast_from_object(TYPE, box.getobj())
+ else:
+ return lltype.cast_to_primitive(TYPE, box.getint())
+
base_dict = {
+ 'ootype': ootype,
'cast_primitive': lltype.cast_primitive,
'cast_adr_to_ptr': llmemory.cast_adr_to_ptr,
'cast_opaque_ptr': lltype.cast_opaque_ptr,
'reveal_ptr': reveal_ptr,
+ 'reveal_obj': reveal_obj,
'GCREF': llmemory.GCREF,
'Signed': lltype.Signed,
'rffi': rffi,
@@ -531,4 +609,5 @@
pass
import pypy.jit.metainterp.executor
-pypy.jit.metainterp.executor.make_execute_list(CPU)
+pypy.jit.metainterp.executor.make_execute_list(LLtypeCPU)
+pypy.jit.metainterp.executor.make_execute_list(OOtypeCPU)
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/minimal/support.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/minimal/support.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/minimal/support.py Mon Apr 27 19:12:02 2009
@@ -7,7 +7,7 @@
from pypy.translator.translator import TranslationContext
from pypy.jit.metainterp.warmspot import WarmRunnerDesc
from pypy.jit.metainterp.simple_optimize import Optimizer
- from pypy.jit.backend.minimal.runner import CPU
+ from pypy.jit.backend.minimal.runner import LLtypeCPU
from pypy.translator.c.genc import CStandaloneBuilder as CBuilder
from pypy.annotation.listdef import s_list_of_strings
from pypy.annotation import model as annmodel
@@ -40,7 +40,7 @@
t.buildannotator().build_types(function, [int] * len(args))
t.buildrtyper().specialize()
warmrunnerdesc = WarmRunnerDesc(t, translate_support_code=True,
- CPUClass=CPU,
+ CPUClass=LLtypeCPU,
optimizer=Optimizer,
**kwds)
warmrunnerdesc.state.set_param_threshold(3) # for tests
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/minimal/test/test_basic.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/minimal/test/test_basic.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/minimal/test/test_basic.py Mon Apr 27 19:12:02 2009
@@ -1,11 +1,14 @@
import py
-from pypy.jit.backend.minimal.runner import CPU
+from pypy.jit.backend.minimal.runner import LLtypeCPU, OOtypeCPU
from pypy.jit.metainterp.test import test_basic
-class JitMixin(test_basic.LLJitMixin):
- CPUClass = CPU
+class LLJitMixin(test_basic.LLJitMixin):
+ CPUClass = LLtypeCPU
-class TestBasic(JitMixin, test_basic.BasicTests):
+class OOJitMixin(test_basic.OOJitMixin):
+ CPUClass = OOtypeCPU
+
+class BasicTests(test_basic.BasicTests):
# for the individual tests see
# ====> ../../../metainterp/test/test_basic.py
@@ -17,3 +20,16 @@
test_bridge_from_interpreter_2 = _skip
test_bridge_from_interpreter_3 = _skip
test_instantiate_classes = _skip
+
+
+class TestOOtype(OOJitMixin, BasicTests):
+ def test_format(self):
+ py.test.skip('in-progress')
+
+ def test_bridge_from_interpreter_4(self):
+ py.test.skip('in-progress')
+
+
+class TestLLtype(LLJitMixin, BasicTests):
+ pass
+
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/minimal/test/test_runner.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/minimal/test/test_runner.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/minimal/test/test_runner.py Mon Apr 27 19:12:02 2009
@@ -1,5 +1,5 @@
import py
-from pypy.jit.backend.minimal.runner import CPU
+from pypy.jit.backend.minimal.runner import LLtypeCPU, OOtypeCPU
from pypy.jit.backend.test.runner import BaseBackendTest
class FakeStats(object):
@@ -13,7 +13,7 @@
# ====> ../../test/runner.py
def setup_class(cls):
- cls.cpu = CPU(rtyper=None, stats=FakeStats())
+ cls.cpu = LLtypeCPU(rtyper=None, stats=FakeStats())
def _skip(self):
py.test.skip("not supported in non-translated version")
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/minimal/test/test_zrpy_exception.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/minimal/test/test_zrpy_exception.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/minimal/test/test_zrpy_exception.py Mon Apr 27 19:12:02 2009
@@ -1,11 +1,11 @@
import py
-from pypy.jit.backend.minimal.runner import CPU
+from pypy.jit.backend.minimal.runner import LLtypeCPU, OOtypeCPU
from pypy.jit.backend.minimal.support import c_meta_interp
from pypy.jit.metainterp.test import test_basic, test_zrpy_exception
class TranslatedJitMixin(test_basic.LLJitMixin):
- CPUClass = CPU
+ CPUClass = LLtypeCPU
def meta_interp(self, *args, **kwds):
return c_meta_interp(*args, **kwds)
More information about the Pypy-commit
mailing list