[pypy-svn] r69958 - in pypy/branch/virtual-forcing/pypy/rlib: . test

arigo at codespeak.net arigo at codespeak.net
Mon Dec 7 23:25:00 CET 2009


Author: arigo
Date: Mon Dec  7 23:24:59 2009
New Revision: 69958

Modified:
   pypy/branch/virtual-forcing/pypy/rlib/_jit_vref.py
   pypy/branch/virtual-forcing/pypy/rlib/jit.py
   pypy/branch/virtual-forcing/pypy/rlib/test/test__jit_vref.py
Log:
Change the way 'None' are accepted: now we can make a non_virtual_ref()
too, that can hide either None or a normal frame.  This is without JIT
support at all: it's just an annotation-level hack to hide and reveal them
as virtual_refs.


Modified: pypy/branch/virtual-forcing/pypy/rlib/_jit_vref.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/rlib/_jit_vref.py	(original)
+++ pypy/branch/virtual-forcing/pypy/rlib/_jit_vref.py	Mon Dec  7 23:24:59 2009
@@ -1,5 +1,5 @@
 from pypy.annotation import model as annmodel
-from pypy.annotation.binaryop import _make_none_union
+from pypy.tool.pairtype import pairtype
 from pypy.rpython.extregistry import ExtRegistryEntry
 from pypy.rpython.rclass import getinstancerepr
 from pypy.rpython.rmodel import Repr
@@ -11,11 +11,14 @@
 
 class SomeVRef(annmodel.SomeObject):
 
-    def __init__(self, s_instance):
+    def __init__(self, s_instance=annmodel.s_None):
+        assert (isinstance(s_instance, annmodel.SomeInstance) or
+                annmodel.s_None.contains(s_instance))
         self.s_instance = s_instance
 
     def can_be_none(self):
-        return True
+        return False    # but it can contain s_None, which is only accessible
+                        # via simple_call() anyway
 
     def simple_call(self):
         return self.s_instance
@@ -26,14 +29,18 @@
     def rtyper_makekey(self):
         return self.__class__,
 
-_make_none_union('SomeVRef', 'obj.s_instance', globals())
+class __extend__(pairtype(SomeVRef, SomeVRef)):
+
+    def union((vref1, vref2)):
+        return SomeVRef(annmodel.unionof(vref1.s_instance, vref2.s_instance))
 
 
 class VRefRepr(Repr):
     lowleveltype = OBJECTPTR
 
     def specialize_call(self, hop):
-        [v] = hop.inputargs(getinstancerepr(hop.rtyper, None))
+        r_generic_object = getinstancerepr(hop.rtyper, None)
+        [v] = hop.inputargs(r_generic_object)   # might generate a cast_pointer
         return v
 
     def rtype_simple_call(self, hop):
@@ -42,8 +49,9 @@
         return hop.genop('cast_pointer', [v], resulttype = hop.r_result)
 
     def convert_const(self, value):
-        if value:
-            raise TyperError("only supports None as a prebuilt virtual_ref")
+        if value() is not None:
+            raise TyperError("only supports virtual_ref_None as a"
+                             " prebuilt virtual_ref")
         return lltype.nullptr(OBJECTPTR.TO)
 
 vrefrepr = VRefRepr()

Modified: pypy/branch/virtual-forcing/pypy/rlib/jit.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/rlib/jit.py	(original)
+++ pypy/branch/virtual-forcing/pypy/rlib/jit.py	Mon Dec  7 23:24:59 2009
@@ -109,12 +109,12 @@
     JIT will abort if it is not), at least between the calls to
     virtual_ref and virtual_ref_finish.  The point is that the 'vref'
     returned by virtual_ref may escape early.  If at runtime it is
-    dereferenced (by calling it, as in 'vref()') before the
+    dereferenced (by the syntax 'vref()' or by virtual_ref_deref()) before the
     virtual_ref_finish, then we get out of the assembler.  If it is not
     dereferenced at all, or only after the virtual_ref_finish, then
     nothing special occurs.
     """
-    return DirectVRef(x)
+    return DirectJitVRef(x)
 virtual_ref.oopspec = 'virtual_ref(x)'
 
 def virtual_ref_finish(x):
@@ -123,16 +123,26 @@
     keepalive_until_here(x)   # otherwise the whole function call is removed
 virtual_ref_finish.oopspec = 'virtual_ref_finish(x)'
 
+def non_virtual_ref(x):
+    """Creates a 'vref' that just returns x when called; nothing more special.
+    Used for None or for frames outside JIT scope."""
+    return DirectVRef(x)
+
+# ---------- implementation-specific ----------
+
 class DirectVRef(object):
     def __init__(self, x):
         self._x = x
     def __call__(self):
         return self._x
-    def _freeze_(self):
-        raise Exception("should not see a prebuilt virtual_ref")
+
+class DirectJitVRef(DirectVRef):
+    def __init__(self, x):
+        assert x is not None, "virtual_ref(None) is not allowed"
+        DirectVRef.__init__(self, x)
 
 class Entry(ExtRegistryEntry):
-    _about_ = DirectVRef
+    _about_ = (non_virtual_ref, DirectJitVRef)
 
     def compute_result_annotation(self, s_obj):
         from pypy.rlib import _jit_vref
@@ -141,6 +151,17 @@
     def specialize_call(self, hop):
         return hop.r_result.specialize_call(hop)
 
+class Entry(ExtRegistryEntry):
+    _type_ = DirectVRef
+
+    def compute_annotation(self):
+        from pypy.rlib import _jit_vref
+        assert isinstance(self.instance, DirectVRef)
+        s_obj = self.bookkeeper.immutablevalue(self.instance())
+        return _jit_vref.SomeVRef(s_obj)
+
+vref_None = non_virtual_ref(None)
+
 # ____________________________________________________________
 # User interface for the hotpath JIT policy
 

Modified: pypy/branch/virtual-forcing/pypy/rlib/test/test__jit_vref.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/rlib/test/test__jit_vref.py	(original)
+++ pypy/branch/virtual-forcing/pypy/rlib/test/test__jit_vref.py	Mon Dec  7 23:24:59 2009
@@ -1,5 +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_vref import SomeVRef
 from pypy.annotation import model as annmodel
 from pypy.annotation.annrpython import RPythonAnnotator
@@ -57,11 +58,12 @@
         if n > 0:
             return virtual_ref(Y())
         else:
-            return virtual_ref(Z())
+            return non_virtual_ref(Z())
     a = RPythonAnnotator()
     s = a.build_types(f, [int])
     assert isinstance(s, SomeVRef)
     assert isinstance(s.s_instance, annmodel.SomeInstance)
+    assert not s.s_instance.can_be_None
     assert s.s_instance.classdef == a.bookkeeper.getuniqueclassdef(X)
 
 def test_annotate_4():
@@ -69,11 +71,12 @@
         if n > 0:
             return virtual_ref(X())
         else:
-            return None
+            return vref_None
     a = RPythonAnnotator()
     s = a.build_types(f, [int])
     assert isinstance(s, SomeVRef)
     assert isinstance(s.s_instance, annmodel.SomeInstance)
+    assert s.s_instance.can_be_None
     assert s.s_instance.classdef == a.bookkeeper.getuniqueclassdef(X)
 
 def test_rtype_1():
@@ -97,7 +100,7 @@
         if n > 0:
             return virtual_ref(Y())
         else:
-            return virtual_ref(Z())
+            return non_virtual_ref(Z())
     x = interpret(f, [-5])
     assert lltype.typeOf(x) == OBJECTPTR
 
@@ -106,7 +109,7 @@
         if n > 0:
             return virtual_ref(X())
         else:
-            return None
+            return vref_None
     x = interpret(f, [-5])
     assert lltype.typeOf(x) == OBJECTPTR
     assert not x



More information about the Pypy-commit mailing list