Author: Antonio Cuni <[email protected]>
Branch: invalidate-virtualrefs
Changeset: r44478:da62de19afc8
Date: 2011-05-25 14:27 +0200
http://bitbucket.org/pypy/pypy/changeset/da62de19afc8/
Log: refactor the untranslated version of vrefs: now they can be in the
non-forced, forced or invalid state
diff --git a/pypy/rlib/jit.py b/pypy/rlib/jit.py
--- a/pypy/rlib/jit.py
+++ b/pypy/rlib/jit.py
@@ -183,7 +183,6 @@
# VRefs
def virtual_ref(x):
-
"""Creates a 'vref' object that contains a reference to 'x'. Calls
to virtual_ref/virtual_ref_finish must be properly nested. The idea
is that the object 'x' is supposed to be JITted as a virtual between
@@ -194,10 +193,9 @@
return DirectJitVRef(x)
virtual_ref.oopspec = 'virtual_ref(x)'
-def virtual_ref_finish(x):
- """See docstring in virtual_ref(x). Note that virtual_ref_finish
- takes as argument the real object, not the vref."""
- keepalive_until_here(x) # otherwise the whole function call is removed
+def virtual_ref_finish(vref, x):
+ """See docstring in virtual_ref(x)"""
+ _virtual_ref_finish(vref, x)
virtual_ref_finish.oopspec = 'virtual_ref_finish(x)'
def non_virtual_ref(x):
@@ -205,19 +203,39 @@
Used for None or for frames outside JIT scope."""
return DirectVRef(x)
+class InvalidVirtualRef(Exception):
+ """
+ Raised if we try to call a non-forced virtualref after the call to
+ virtual_ref_finish
+ """
+
# ---------- implementation-specific ----------
class DirectVRef(object):
def __init__(self, x):
self._x = x
+ self._state = 'non-forced'
+
def __call__(self):
+ if self._state == 'non-forced':
+ self._state = 'forced'
+ elif self._state == 'invalid':
+ raise InvalidVirtualRef
return self._x
+ def _finish(self):
+ if self._state == 'non-forced':
+ self._state = 'invalid'
+
class DirectJitVRef(DirectVRef):
def __init__(self, x):
assert x is not None, "virtual_ref(None) is not allowed"
DirectVRef.__init__(self, x)
+def _virtual_ref_finish(vref, x):
+ assert vref._x is x, "Invalid call to virtual_ref_finish"
+ vref._finish()
+
class Entry(ExtRegistryEntry):
_about_ = (non_virtual_ref, DirectJitVRef)
diff --git a/pypy/rlib/test/test__jit_vref.py b/pypy/rlib/test/test__jit_vref.py
--- a/pypy/rlib/test/test__jit_vref.py
+++ b/pypy/rlib/test/test__jit_vref.py
@@ -1,6 +1,6 @@
import py
from pypy.rlib.jit import virtual_ref, virtual_ref_finish
-from pypy.rlib.jit import vref_None, non_virtual_ref
+from pypy.rlib.jit import vref_None, non_virtual_ref, InvalidVirtualRef
from pypy.rlib._jit_vref import SomeVRef
from pypy.annotation import model as annmodel
from pypy.annotation.annrpython import RPythonAnnotator
@@ -23,18 +23,23 @@
pass
-def test_direct_1():
+def test_direct_forced():
x1 = X()
vref = virtual_ref(x1)
+ assert vref._state == 'non-forced'
assert vref() is x1
- virtual_ref_finish(x1)
+ assert vref._state == 'forced'
+ virtual_ref_finish(vref, x1)
+ assert vref._state == 'forced'
assert vref() is x1
-def test_direct_2():
+def test_direct_invalid():
x1 = X()
vref = virtual_ref(x1)
- virtual_ref_finish(x1)
- assert vref() is x1
+ assert vref._state == 'non-forced'
+ virtual_ref_finish(vref, x1)
+ assert vref._state == 'invalid'
+ py.test.raises(InvalidVirtualRef, "vref()")
def test_annotate_1():
def f():
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit