[pypy-svn] r65996 - in pypy/branch/pyjitpl5/pypy: jit/metainterp jit/metainterp/test rpython/ootypesystem
arigo at codespeak.net
arigo at codespeak.net
Fri Jun 26 15:18:21 CEST 2009
Author: arigo
Date: Fri Jun 26 15:18:18 2009
New Revision: 65996
Modified:
pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py
pypy/branch/pyjitpl5/pypy/jit/metainterp/virtualizable.py
pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py
pypy/branch/pyjitpl5/pypy/rpython/ootypesystem/rclass.py
pypy/branch/pyjitpl5/pypy/rpython/ootypesystem/rvirtualizable2.py
Log:
Just enough to make test_external_access_while_tracing pass.
Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py Fri Jun 26 15:18:18 2009
@@ -1150,9 +1150,15 @@
@specialize.arg(1)
def execute_and_record(self, opnum, argboxes, descr=None):
- # execute the operation first
history.check_descr(descr)
+ # residual calls require attention to keep virtualizables in-sync
+ require_attention = (opnum == rop.CALL or opnum == rop.CALL_PURE)
+ if require_attention:
+ self.before_residual_call()
+ # execute the operation
resbox = executor.execute(self.cpu, opnum, argboxes, descr)
+ if require_attention:
+ require_attention = self.after_residual_call()
# check if the operation can be constant-folded away
canfold = False
if rop._ALWAYS_PURE_FIRST <= opnum <= rop._ALWAYS_PURE_LAST:
@@ -1172,6 +1178,8 @@
and self.framestack):
op.pc = self.framestack[-1].pc
op.name = self.framestack[-1].jitcode.name
+ if require_attention:
+ self.after_generate_residual_call()
return resbox
def _interpret(self):
@@ -1474,6 +1482,39 @@
virtualizable)
original_boxes += self.virtualizable_boxes
self.virtualizable_boxes.append(virtualizable_box)
+ self.initialize_virtualizable_enter()
+
+ def initialize_virtualizable_enter(self):
+ vinfo = self.staticdata.virtualizable_info
+ virtualizable_box = self.virtualizable_boxes[-1]
+ virtualizable = vinfo.unwrap_virtualizable_box(virtualizable_box)
+ vinfo.tracing_enter(virtualizable)
+
+ def before_residual_call(self):
+ vinfo = self.staticdata.virtualizable_info
+ if vinfo is not None:
+ virtualizable_box = self.virtualizable_boxes[-1]
+ virtualizable = vinfo.unwrap_virtualizable_box(virtualizable_box)
+ vinfo.tracing_before_residual_call(virtualizable)
+
+ def after_residual_call(self):
+ vinfo = self.staticdata.virtualizable_info
+ if vinfo is not None:
+ virtualizable_box = self.virtualizable_boxes[-1]
+ virtualizable = vinfo.unwrap_virtualizable_box(virtualizable_box)
+ if vinfo.tracing_after_residual_call(virtualizable):
+ # This is before the residual call is actually generated.
+ # We first generate a store-everything-back.
+ self.gen_store_back_in_virtualizable()
+ return True # must call after_generate_residual_call()
+ return False # don't call after_generate_residual_call()
+
+ def after_generate_residual_call(self):
+ # Called after generating a residual call, and only if
+ # after_residual_call() returned True, i.e. if code in the residual
+ # call causes the virtualizable to escape. Reload the modified
+ # fields of the virtualizable.
+ self.gen_load_fields_from_virtualizable()
def handle_exception(self):
etype = self.cpu.get_exception()
@@ -1500,6 +1541,7 @@
if self.staticdata.virtualizable_info is not None:
self.virtualizable_boxes = _consume_nums(vable_nums,
newboxes, consts)
+ self.initialize_virtualizable_enter()
self.synchronize_virtualizable()
#
self.framestack = []
@@ -1521,6 +1563,27 @@
virtualizable = vinfo.unwrap_virtualizable_box(virtualizable_box)
vinfo.write_boxes(virtualizable, self.virtualizable_boxes)
+ def gen_load_fields_from_virtualizable(self):
+ vinfo = self.staticdata.virtualizable_info
+ if vinfo is not None:
+ vbox = self.virtualizable_boxes[-1]
+ for i in range(vinfo.num_static_extra_boxes):
+ fieldbox = self.execute_and_record(rop.GETFIELD_GC, [vbox],
+ descr=vinfo.static_field_descrs[i])
+ self.virtualizable_boxes[i] = fieldbox
+ i = vinfo.num_static_extra_boxes
+ virtualizable = vinfo.unwrap_virtualizable_box(vbox)
+ for k in range(vinfo.num_arrays):
+ abox = self.execute_and_record(rop.GETFIELD_GC, [vbox],
+ descr=vinfo.array_field_descrs[k])
+ for j in range(vinfo.get_array_length(virtualizable, k)):
+ itembox = self.execute_and_record(rop.GETARRAYITEM_GC,
+ [abox, ConstInt(j)],
+ descr=vinfo.array_descrs[k])
+ self.virtualizable_boxes[i] = itembox
+ i += 1
+ assert i + 1 == len(self.virtualizable_boxes)
+
def gen_store_back_in_virtualizable(self):
vinfo = self.staticdata.virtualizable_info
if vinfo is not None:
Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py Fri Jun 26 15:18:18 2009
@@ -174,7 +174,6 @@
self.check_loops(getfield_gc=1, setfield_gc=1)
def test_external_access_while_tracing(self):
- py.test.skip("in-progress")
myjitdriver = JitDriver(greens = [], reds = ['n', 'm', 'xy'],
virtualizables = ['xy'])
class Outer:
@@ -202,7 +201,7 @@
assert f(20) == 10000*20 + (20*21)/2
res = self.meta_interp(f, [20], policy=StopAtXPolicy(ext))
assert res == 10000*20 + (20*21)/2
- self.check_loops(call_pure=1, getfield_gc=2, setfield_gc=2)
+ self.check_loops(call=1, getfield_gc=2, setfield_gc=2)
# xxx for now a call that forces the virtualizable during tracing
# is supposed to always force it later too.
Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/virtualizable.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/virtualizable.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/virtualizable.py Fri Jun 26 15:18:18 2009
@@ -1,6 +1,9 @@
from pypy.rpython.lltypesystem import lltype
from pypy.rpython.ootypesystem import ootype
+from pypy.rpython.annlowlevel import cast_instance_to_base_ptr
+from pypy.rpython.annlowlevel import cast_base_ptr_to_instance
from pypy.rpython import rvirtualizable2
+from pypy.rlib.objectmodel import we_are_translated
from pypy.rlib.unroll import unrolling_iterable
from pypy.jit.metainterp.typesystem import deref
from pypy.jit.metainterp import history
@@ -13,6 +16,15 @@
jitdriver = warmrunnerdesc.jitdriver
cpu = warmrunnerdesc.cpu
self.is_oo = cpu.is_oo
+ if not self.is_oo:
+ from pypy.rpython.lltypesystem.rvirtualizable2 import VABLERTIPTR
+ self.VABLERTI = VABLERTIPTR
+ self.null_vable_rti = lltype.nullptr(VABLERTIPTR.TO)
+ else:
+ from pypy.rpython.ootypesystem.rvirtualizable2 import VABLERTI
+ self.VABLERTI = VABLERTI
+ self.null_vable_rti = ootype.make_null_instance(VABLERTI)
+ #
assert len(jitdriver.virtualizables) == 1 # for now
[vname] = jitdriver.virtualizables
index = len(jitdriver.greens) + jitdriver.reds.index(vname)
@@ -155,14 +167,9 @@
if self.is_oo:
return # XXX implement me
#
- def force_now(virtualizable):
- rti = virtualizable.vable_rti
- pass # XXX in-progress
- force_now._dont_inline_ = True
- #
def force_if_necessary(virtualizable):
if virtualizable.vable_rti:
- force_now(virtualizable)
+ self.force_now(virtualizable)
force_if_necessary._always_inline_ = True
#
all_graphs = self.warmrunnerdesc.translator.graphs
@@ -188,3 +195,59 @@
def is_vtypeptr(self, TYPE):
return rvirtualizable2.match_virtualizable_type(TYPE, self.VTYPEPTR)
+
+ def cast_instance_to_base_ptr(self, vable_rti):
+ if we_are_translated():
+ return cast_instance_to_base_ptr(vable_rti)
+ else:
+ vable_rti._TYPE = self.VABLERTI # hack for non-translated mode
+ return vable_rti
+
+ def tracing_enter(self, virtualizable):
+ if virtualizable.vable_rti:
+ self.force_now(virtualizable)
+ assert not virtualizable.vable_rti
+
+ def tracing_before_residual_call(self, virtualizable):
+ assert not virtualizable.vable_rti
+ ptr = self.cast_instance_to_base_ptr(tracing_vable_rti)
+ virtualizable.vable_rti = ptr
+
+ def tracing_after_residual_call(self, virtualizable):
+ if virtualizable.vable_rti:
+ # not modified by the residual call; assert that it is still
+ # set to 'tracing_vable_rti' and clear it.
+ ptr = self.cast_instance_to_base_ptr(tracing_vable_rti)
+ assert virtualizable.vable_rti == ptr
+ virtualizable.vable_rti = self.null_vable_rti
+ return False
+ else:
+ # marker "modified during residual call" set.
+ return True
+
+ def force_now(self, virtualizable):
+ rti = virtualizable.vable_rti
+ virtualizable.vable_rti = self.null_vable_rti
+ if we_are_translated():
+ rti = cast_base_ptr_to_instance(AbstractVableRti, rti)
+ rti.force_now(virtualizable)
+ force_now._dont_inline_ = True
+
+# ____________________________________________________________
+
+
+class AbstractVableRti(object):
+
+ def force_now(self, virtualizable):
+ raise NotImplementedError
+
+
+class TracingVableRti(AbstractVableRti):
+
+ def force_now(self, virtualizable):
+ # The values if the virtualizable are always correct during tracing.
+ # We only need to set a marker to tell that forcing occurred.
+ # As the caller resets vable_rti to NULL, it plays the role of marker.
+ pass
+
+tracing_vable_rti = TracingVableRti()
Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py Fri Jun 26 15:18:18 2009
@@ -8,7 +8,7 @@
from pypy.rpython.test.test_llinterp import get_interpreter, clear_tcache
from pypy.objspace.flow.model import SpaceOperation, Variable, Constant
from pypy.objspace.flow.model import checkgraph, Link, copygraph
-from pypy.rlib.objectmodel import we_are_translated, UnboxedValue, specialize
+from pypy.rlib.objectmodel import we_are_translated
from pypy.rlib.unroll import unrolling_iterable
from pypy.rlib.jit import PARAMETERS
from pypy.rlib.rarithmetic import r_uint, intmask
Modified: pypy/branch/pyjitpl5/pypy/rpython/ootypesystem/rclass.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/rpython/ootypesystem/rclass.py (original)
+++ pypy/branch/pyjitpl5/pypy/rpython/ootypesystem/rclass.py Fri Jun 26 15:18:18 2009
@@ -190,7 +190,7 @@
self.object_type = self.lowleveltype
self.gcflavor = gcflavor
- def _setup_repr(self, hints=None):
+ def _setup_repr(self, llfields=None, hints=None):
if hints:
self.lowleveltype._hints.update(hints)
@@ -212,6 +212,9 @@
fields = {}
fielddefaults = {}
+
+ if llfields:
+ fields.update(dict(llfields))
selfattrs = self.classdef.attrs
Modified: pypy/branch/pyjitpl5/pypy/rpython/ootypesystem/rvirtualizable2.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/rpython/ootypesystem/rvirtualizable2.py (original)
+++ pypy/branch/pyjitpl5/pypy/rpython/ootypesystem/rvirtualizable2.py Fri Jun 26 15:18:18 2009
@@ -1,9 +1,11 @@
from pypy.rpython.rmodel import inputconst
from pypy.rpython.ootypesystem import ootype
-from pypy.rpython.ootypesystem.rclass import InstanceRepr, mangle
+from pypy.rpython.ootypesystem.rclass import InstanceRepr, mangle, OBJECT
from pypy.rpython.rvirtualizable2 import AbstractVirtualizableAccessor
from pypy.rpython.rvirtualizable2 import AbstractVirtualizable2InstanceRepr
+VABLERTI = OBJECT
+
class VirtualizableAccessor(AbstractVirtualizableAccessor):
pass
@@ -14,7 +16,10 @@
VirtualizableAccessor = VirtualizableAccessor
def _setup_repr_llfields(self):
- return None # TODO
+ llfields = []
+ if self.top_of_virtualizable_hierarchy:
+ llfields.append(('vable_rti', VABLERTI))
+ return llfields
def get_field(self, attr):
mangled = mangle(attr, self.rtyper.getconfig())
More information about the Pypy-commit
mailing list