Author: Carl Friedrich Bolz <[email protected]>
Branch: small-unroll-improvements
Changeset: r70646:4b34877aa5e4
Date: 2014-04-15 16:54 +0200
http://bitbucket.org/pypy/pypy/changeset/4b34877aa5e4/

Log:    disentangle resume and virtualstate which have *nothing* at all to
        do with each other conceptually

        introduce a slightly weird virtual walking api to do that

diff --git a/rpython/jit/metainterp/optimizeopt/optimizer.py 
b/rpython/jit/metainterp/optimizeopt/optimizer.py
--- a/rpython/jit/metainterp/optimizeopt/optimizer.py
+++ b/rpython/jit/metainterp/optimizeopt/optimizer.py
@@ -135,13 +135,21 @@
     def force_at_end_of_preamble(self, already_forced, optforce):
         return self
 
-    def get_args_for_fail(self, modifier):
+    # visitor API
+
+    def visitor_walk_recursive(self, visitor):
         pass
 
-    def make_virtual_info(self, modifier, fieldnums):
-        #raise NotImplementedError # should not be called on this level
-        assert fieldnums is None
-        return modifier.make_not_virtual(self)
+    @specialize.argtype(1)
+    def visitor_dispatch_virtual_type(self, visitor):
+        if self.is_virtual():
+            return self._visitor_dispatch_virtual_type(visitor)
+        else:
+            return visitor.visit_not_virtual(self)
+
+    @specialize.argtype(1)
+    def _visitor_dispatch_virtual_type(self, visitor):
+        assert 0, "unreachable"
 
     def is_constant(self):
         return self.level == LEVEL_CONSTANT
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py 
b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
@@ -61,24 +61,6 @@
     lst6 = virt1._get_field_descr_list()
     assert lst6 is lst3
 
-def test_reuse_vinfo():
-    class FakeVInfo(object):
-        def set_content(self, fieldnums):
-            self.fieldnums = fieldnums
-        def equals(self, fieldnums):
-            return self.fieldnums == fieldnums
-    class FakeVirtualValue(virtualize.AbstractVirtualValue):
-        def _make_virtual(self, *args):
-            return FakeVInfo()
-    v1 = FakeVirtualValue(None, None)
-    vinfo1 = v1.make_virtual_info(None, [1, 2, 4])
-    vinfo2 = v1.make_virtual_info(None, [1, 2, 4])
-    assert vinfo1 is vinfo2
-    vinfo3 = v1.make_virtual_info(None, [1, 2, 6])
-    assert vinfo3 is not vinfo2
-    vinfo4 = v1.make_virtual_info(None, [1, 2, 6])
-    assert vinfo3 is vinfo4
-
 def test_descrlist_dict():
     from rpython.jit.metainterp.optimizeopt import util as optimizeutil
     h1 = optimizeutil.descrlist_hash([])
diff --git a/rpython/jit/metainterp/optimizeopt/unroll.py 
b/rpython/jit/metainterp/optimizeopt/unroll.py
--- a/rpython/jit/metainterp/optimizeopt/unroll.py
+++ b/rpython/jit/metainterp/optimizeopt/unroll.py
@@ -6,7 +6,7 @@
 from rpython.jit.metainterp.optimize import InvalidLoop
 from rpython.jit.metainterp.optimizeopt.generalize import KillHugeIntBounds
 from rpython.jit.metainterp.optimizeopt.optimizer import Optimizer, 
Optimization
-from rpython.jit.metainterp.optimizeopt.virtualstate import (VirtualStateAdder,
+from rpython.jit.metainterp.optimizeopt.virtualstate import 
(VirtualStateConstructor,
         ShortBoxes, BadVirtualState, VirtualStatesCantMatch)
 from rpython.jit.metainterp.resoperation import rop, ResOperation
 from rpython.jit.metainterp.resume import Snapshot
@@ -55,7 +55,7 @@
         self.boxes_created_this_iteration = None
 
     def get_virtual_state(self, args):
-        modifier = VirtualStateAdder(self.optimizer)
+        modifier = VirtualStateConstructor(self.optimizer)
         return modifier.get_virtual_state(args)
 
     def fix_snapshot(self, jump_args, snapshot):
diff --git a/rpython/jit/metainterp/optimizeopt/virtualize.py 
b/rpython/jit/metainterp/optimizeopt/virtualize.py
--- a/rpython/jit/metainterp/optimizeopt/virtualize.py
+++ b/rpython/jit/metainterp/optimizeopt/virtualize.py
@@ -10,7 +10,7 @@
 
 from rpython.jit.metainterp.optimizeopt.rawbuffer import RawBuffer, 
InvalidRawOperation
 from rpython.jit.metainterp.resoperation import rop, ResOperation
-from rpython.rlib.objectmodel import we_are_translated
+from rpython.rlib.objectmodel import we_are_translated, specialize
 
 
 class AbstractVirtualValue(optimizer.OptValue):
@@ -45,27 +45,17 @@
             return value
         return OptValue(self.force_box(optforce))
 
-    def get_args_for_fail(self, modifier):
+    def visitor_walk_recursive(self, visitor):
         # checks for recursion: it is False unless
         # we have already seen the very same keybox
-        if self.box is None and not modifier.already_seen_virtual(self.keybox):
-            self._get_args_for_fail(modifier)
+        if self.box is None and not visitor.already_seen_virtual(self.keybox):
+            self._visitor_walk_recursive(visitor)
 
-    def _get_args_for_fail(self, modifier):
+    def _visitor_walk_recursive(self, visitor):
         raise NotImplementedError("abstract base")
 
-    def make_virtual_info(self, modifier, fieldnums):
-        if fieldnums is None:
-            return self._make_virtual(modifier)
-        vinfo = self._cached_vinfo
-        if vinfo is not None and vinfo.equals(fieldnums):
-            return vinfo
-        vinfo = self._make_virtual(modifier)
-        vinfo.set_content(fieldnums)
-        self._cached_vinfo = vinfo
-        return vinfo
-
-    def _make_virtual(self, modifier):
+    @specialize.argtype(1)
+    def _visitor_dispatch_virtual_type(self, visitor):
         raise NotImplementedError("abstract base")
 
     def _really_force(self, optforce):
@@ -202,13 +192,13 @@
             self._cached_sorted_fields = lst
         return lst
 
-    def _get_args_for_fail(self, modifier):
+    def _visitor_walk_recursive(self, visitor):
         lst = self._get_field_descr_list()
         fieldboxes = [self._fields[ofs].get_key_box() for ofs in lst]
-        modifier.register_virtual_fields(self.keybox, fieldboxes)
+        visitor.register_virtual_fields(self.keybox, fieldboxes)
         for ofs in lst:
             fieldvalue = self._fields[ofs]
-            fieldvalue.get_args_for_fail(modifier)
+            fieldvalue.visitor_walk_recursive(visitor)
 
 class VirtualValue(AbstractVirtualStructValue):
     level = optimizer.LEVEL_KNOWNCLASS
@@ -218,9 +208,10 @@
         assert isinstance(known_class, Const)
         self.known_class = known_class
 
-    def _make_virtual(self, modifier):
+    @specialize.argtype(1)
+    def _visitor_dispatch_virtual_type(self, visitor):
         fielddescrs = self._get_field_descr_list()
-        return modifier.make_virtual(self.known_class, fielddescrs)
+        return visitor.visit_virtual(self.known_class, fielddescrs)
 
     def _get_descr(self):
         return vtable2descr(self.cpu, self.known_class.getint())
@@ -238,9 +229,10 @@
         AbstractVirtualStructValue.__init__(self, cpu, keybox, source_op)
         self.structdescr = structdescr
 
-    def _make_virtual(self, modifier):
+    @specialize.argtype(1)
+    def _visitor_dispatch_virtual_type(self, visitor):
         fielddescrs = self._get_field_descr_list()
-        return modifier.make_vstruct(self.structdescr, fielddescrs)
+        return visitor.visit_vstruct(self.structdescr, fielddescrs)
 
     def _get_descr(self):
         return self.structdescr
@@ -260,15 +252,15 @@
     def set_item_value(self, i, newval):
         raise NotImplementedError
 
-    def _get_args_for_fail(self, modifier):
+    def _visitor_walk_recursive(self, visitor):
         itemboxes = []
         for i in range(self.getlength()):
             itemvalue = self.get_item_value(i)
             itemboxes.append(itemvalue.get_key_box())
-        modifier.register_virtual_fields(self.keybox, itemboxes)
+        visitor.register_virtual_fields(self.keybox, itemboxes)
         for i in range(self.getlength()):
             itemvalue = self.get_item_value(i)
-            itemvalue.get_args_for_fail(modifier)
+            itemvalue.visitor_walk_recursive(visitor)
 
 
 class VArrayValue(AbstractVArrayValue):
@@ -326,8 +318,9 @@
                                   descr=self.arraydescr)
                 optforce.emit_operation(op)
 
-    def _make_virtual(self, modifier):
-        return modifier.make_varray(self.arraydescr)
+    @specialize.argtype(1)
+    def _visitor_dispatch_virtual_type(self, visitor):
+        return visitor.visit_varray(self.arraydescr)
 
 
 class VArrayStructValue(AbstractVirtualValue):
@@ -373,16 +366,16 @@
             descrs.append(item_descrs)
         return descrs
 
-    def _get_args_for_fail(self, modifier):
+    def _visitor_walk_recursive(self, visitor):
         itemdescrs = self._get_list_of_descrs()
         itemboxes = []
         for i in range(len(self._items)):
             for descr in itemdescrs[i]:
                 itemboxes.append(self._items[i][descr].get_key_box())
-        modifier.register_virtual_fields(self.keybox, itemboxes)
+        visitor.register_virtual_fields(self.keybox, itemboxes)
         for i in range(len(self._items)):
             for descr in itemdescrs[i]:
-                self._items[i][descr].get_args_for_fail(modifier)
+                self._items[i][descr].visitor_walk_recursive(visitor)
 
     def force_at_end_of_preamble(self, already_forced, optforce):
         if self in already_forced:
@@ -393,8 +386,9 @@
                 self._items[index][descr] = 
self._items[index][descr].force_at_end_of_preamble(already_forced, optforce)
         return self
 
-    def _make_virtual(self, modifier):
-        return modifier.make_varraystruct(self.arraydescr, 
self._get_list_of_descrs())
+    @specialize.argtype(1)
+    def _visitor_dispatch_virtual_type(self, visitor):
+        return visitor.visit_varraystruct(self.arraydescr, 
self._get_list_of_descrs())
 
 
 class VRawBufferValue(AbstractVArrayValue):
@@ -442,11 +436,12 @@
                               descr=descr)
             optforce.emit_operation(op)
 
-    def _make_virtual(self, modifier):
+    @specialize.argtype(1)
+    def _visitor_dispatch_virtual_type(self, visitor):
         # I *think* we need to make a copy of offsets and descrs because we
         # want a snapshot of the virtual state right now: if we grow more
         # elements later, we don't want them to go in this virtual state
-        return modifier.make_vrawbuffer(self.size,
+        return visitor.visit_vrawbuffer(self.size,
                                         self.buffer.offsets[:],
                                         self.buffer.descrs[:])
 
@@ -474,13 +469,14 @@
     def getitem_raw(self, offset, length, descr):
         return self.rawbuffer_value.getitem_raw(self.offset+offset, length, 
descr)
 
-    def _get_args_for_fail(self, modifier):
+    def _visitor_walk_recursive(self, visitor):
         box = self.rawbuffer_value.get_key_box()
-        modifier.register_virtual_fields(self.keybox, [box])
-        self.rawbuffer_value.get_args_for_fail(modifier)
+        visitor.register_virtual_fields(self.keybox, [box])
+        self.rawbuffer_value.visitor_walk_recursive(visitor)
 
-    def _make_virtual(self, modifier):
-        return modifier.make_vrawslice(self.offset)
+    @specialize.argtype(1)
+    def _visitor_dispatch_virtual_type(self, visitor):
+        return visitor.visit_vrawslice(self.offset)
 
 
 class OptVirtualize(optimizer.Optimization):
diff --git a/rpython/jit/metainterp/optimizeopt/virtualstate.py 
b/rpython/jit/metainterp/optimizeopt/virtualstate.py
--- a/rpython/jit/metainterp/optimizeopt/virtualstate.py
+++ b/rpython/jit/metainterp/optimizeopt/virtualstate.py
@@ -1,4 +1,4 @@
-from rpython.jit.metainterp import resume
+from rpython.jit.metainterp.walkvirtual import VirtualVisitor
 from rpython.jit.metainterp.history import (BoxInt, ConstInt, BoxPtr, Const,
         ConstPtr, ConstFloat)
 from rpython.jit.metainterp.optimizeopt import virtualize
@@ -7,7 +7,7 @@
     LEVEL_KNOWNCLASS, LEVEL_NONNULL, LEVEL_UNKNOWN, OptValue)
 from rpython.jit.metainterp.resoperation import rop, ResOperation
 from rpython.rlib.debug import debug_start, debug_stop, debug_print
-from rpython.rlib.objectmodel import we_are_translated
+from rpython.rlib.objectmodel import we_are_translated, import_from_mixin
 
 
 class BadVirtualState(Exception):
@@ -31,7 +31,7 @@
             bad = {}
         self.bad = bad
 
-class AbstractVirtualStateInfo(resume.AbstractVirtualInfo):
+class AbstractVirtualStateInfo(object):
     position = -1
 
     def generate_guards(self, other, value, state):
@@ -506,7 +506,9 @@
             s.debug_print("    ", seen, bad, metainterp_sd)
 
 
-class VirtualStateAdder(resume.ResumeDataVirtualAdder):
+class VirtualStateConstructor(object):
+    import_from_mixin(VirtualVisitor)
+
     def __init__(self, optimizer):
         self.fieldboxes = {}
         self.optimizer = optimizer
@@ -527,12 +529,10 @@
         try:
             info = self.info[box]
         except KeyError:
+            self.info[box] = info = value.visitor_dispatch_virtual_type(self)
             if value.is_virtual():
-                self.info[box] = info = value.make_virtual_info(self, None)
                 flds = self.fieldboxes[box]
                 info.fieldstate = [self.state(b) for b in flds]
-            else:
-                self.info[box] = info = self.make_not_virtual(value)
         return info
 
     def get_virtual_state(self, jump_args):
@@ -547,31 +547,25 @@
                   for box in jump_args]
 
         for value in values:
-            if value.is_virtual():
-                value.get_args_for_fail(self)
-            else:
-                self.make_not_virtual(value)
+            value.visitor_walk_recursive(self)
         return VirtualState([self.state(box) for box in jump_args])
 
-    def make_not_virtual(self, value):
+    def visit_not_virtual(self, value):
         is_opaque = value in self.optimizer.opaque_pointers
         return NotVirtualStateInfo(value, is_opaque)
 
-    def make_virtual(self, known_class, fielddescrs):
+    def visit_virtual(self, known_class, fielddescrs):
         return VirtualStateInfo(known_class, fielddescrs)
 
-    def make_vstruct(self, typedescr, fielddescrs):
+    def visit_vstruct(self, typedescr, fielddescrs):
         return VStructStateInfo(typedescr, fielddescrs)
 
-    def make_varray(self, arraydescr):
+    def visit_varray(self, arraydescr):
         return VArrayStateInfo(arraydescr)
 
-    def make_varraystruct(self, arraydescr, fielddescrs):
+    def visit_varraystruct(self, arraydescr, fielddescrs):
         return VArrayStructStateInfo(arraydescr, fielddescrs)
 
-    def make_vrawbuffer(self, size, offsets, descrs):
-        raise NotImplementedError
-
 
 class BoxNotProducable(Exception):
     pass
diff --git a/rpython/jit/metainterp/optimizeopt/vstring.py 
b/rpython/jit/metainterp/optimizeopt/vstring.py
--- a/rpython/jit/metainterp/optimizeopt/vstring.py
+++ b/rpython/jit/metainterp/optimizeopt/vstring.py
@@ -199,22 +199,22 @@
             offsetbox = _int_add(string_optimizer, offsetbox, CONST_1)
         return offsetbox
 
-    def get_args_for_fail(self, modifier):
-        if self.box is None and not modifier.already_seen_virtual(self.keybox):
-            charboxes = []
-            for value in self._chars:
-                if value is not None:
-                    box = value.get_key_box()
-                else:
-                    box = None
-                charboxes.append(box)
-            modifier.register_virtual_fields(self.keybox, charboxes)
-            for value in self._chars:
-                if value is not None:
-                    value.get_args_for_fail(modifier)
+    def _visitor_walk_recursive(self, visitor):
+        charboxes = []
+        for value in self._chars:
+            if value is not None:
+                box = value.get_key_box()
+            else:
+                box = None
+            charboxes.append(box)
+        visitor.register_virtual_fields(self.keybox, charboxes)
+        for value in self._chars:
+            if value is not None:
+                value.visitor_walk_recursive(visitor)
 
-    def _make_virtual(self, modifier):
-        return modifier.make_vstrplain(self.mode is mode_unicode)
+    @specialize.argtype(1)
+    def _visitor_dispatch_virtual_type(self, visitor):
+        return visitor.visit_vstrplain(self.mode is mode_unicode)
 
 
 class VStringConcatValue(VAbstractStringValue):
@@ -256,18 +256,18 @@
                                                  offsetbox, mode)
         return offsetbox
 
-    def get_args_for_fail(self, modifier):
-        if self.box is None and not modifier.already_seen_virtual(self.keybox):
-            # we don't store the lengthvalue in guards, because the
-            # guard-failed code starts with a regular STR_CONCAT again
-            leftbox = self.left.get_key_box()
-            rightbox = self.right.get_key_box()
-            modifier.register_virtual_fields(self.keybox, [leftbox, rightbox])
-            self.left.get_args_for_fail(modifier)
-            self.right.get_args_for_fail(modifier)
+    def _visitor_walk_recursive(self, visitor):
+        # we don't store the lengthvalue in guards, because the
+        # guard-failed code starts with a regular STR_CONCAT again
+        leftbox = self.left.get_key_box()
+        rightbox = self.right.get_key_box()
+        visitor.register_virtual_fields(self.keybox, [leftbox, rightbox])
+        self.left.visitor_walk_recursive(visitor)
+        self.right.visitor_walk_recursive(visitor)
 
-    def _make_virtual(self, modifier):
-        return modifier.make_vstrconcat(self.mode is mode_unicode)
+    @specialize.argtype(1)
+    def _visitor_dispatch_virtual_type(self, visitor):
+        return visitor.visit_vstrconcat(self.mode is mode_unicode)
 
 
 class VStringSliceValue(VAbstractStringValue):
@@ -302,18 +302,18 @@
                                 self.vstart.force_box(string_optimizer), 
offsetbox,
                                 lengthbox, mode)
 
-    def get_args_for_fail(self, modifier):
-        if self.box is None and not modifier.already_seen_virtual(self.keybox):
-            boxes = [self.vstr.get_key_box(),
-                     self.vstart.get_key_box(),
-                     self.vlength.get_key_box()]
-            modifier.register_virtual_fields(self.keybox, boxes)
-            self.vstr.get_args_for_fail(modifier)
-            self.vstart.get_args_for_fail(modifier)
-            self.vlength.get_args_for_fail(modifier)
+    def _visitor_walk_recursive(self, visitor):
+        boxes = [self.vstr.get_key_box(),
+                 self.vstart.get_key_box(),
+                 self.vlength.get_key_box()]
+        visitor.register_virtual_fields(self.keybox, boxes)
+        self.vstr.visitor_walk_recursive(visitor)
+        self.vstart.visitor_walk_recursive(visitor)
+        self.vlength.visitor_walk_recursive(visitor)
 
-    def _make_virtual(self, modifier):
-        return modifier.make_vstrslice(self.mode is mode_unicode)
+    @specialize.argtype(1)
+    def _visitor_dispatch_virtual_type(self, visitor):
+        return visitor.visit_vstrslice(self.mode is mode_unicode)
 
 
 def copy_str_content(string_optimizer, srcbox, targetbox,
diff --git a/rpython/jit/metainterp/resume.py b/rpython/jit/metainterp/resume.py
--- a/rpython/jit/metainterp/resume.py
+++ b/rpython/jit/metainterp/resume.py
@@ -4,12 +4,14 @@
     BoxInt, BoxPtr, BoxFloat, INT, REF, FLOAT, AbstractDescr)
 from rpython.jit.metainterp.resoperation import rop
 from rpython.rlib import rarithmetic, rstack
-from rpython.rlib.objectmodel import we_are_translated, specialize, 
compute_unique_id
+from rpython.rlib.objectmodel import (we_are_translated, specialize,
+        compute_unique_id, import_from_mixin)
 from rpython.rlib.debug import (have_debug_prints, ll_assert, debug_start,
     debug_stop, debug_print)
 from rpython.rtyper import annlowlevel
 from rpython.rtyper.lltypesystem import lltype, llmemory, rffi, rstr
 from rpython.rtyper.lltypesystem.rclass import OBJECTPTR
+from rpython.jit.metainterp.walkvirtual import VirtualVisitor
 
 
 # Logic to encode the chain of frames and the state of the boxes at a
@@ -267,42 +269,60 @@
 
 
 class ResumeDataVirtualAdder(object):
+    import_from_mixin(VirtualVisitor)
+
     def __init__(self, storage, memo):
         self.storage = storage
         self.memo = memo
 
-    def make_virtual(self, known_class, fielddescrs):
+    def make_virtual_info(self, value, fieldnums):
+        assert fieldnums is not None
+        vinfo = value._cached_vinfo
+        if vinfo is not None and vinfo.equals(fieldnums):
+            return vinfo
+        vinfo = value.visitor_dispatch_virtual_type(self)
+        vinfo.set_content(fieldnums)
+        value._cached_vinfo = vinfo
+        return vinfo
+
+    def visit_not_virtual(self, value):
+        assert 0, "unreachable"
+
+    def visit_virtual(self, known_class, fielddescrs):
         return VirtualInfo(known_class, fielddescrs)
 
-    def make_vstruct(self, typedescr, fielddescrs):
+    def visit_vstruct(self, typedescr, fielddescrs):
         return VStructInfo(typedescr, fielddescrs)
 
-    def make_varray(self, arraydescr):
+    def visit_varray(self, arraydescr):
         return VArrayInfo(arraydescr)
 
-    def make_varraystruct(self, arraydescr, fielddescrs):
+    def visit_varraystruct(self, arraydescr, fielddescrs):
         return VArrayStructInfo(arraydescr, fielddescrs)
 
-    def make_vrawbuffer(self, size, offsets, descrs):
+    def visit_vrawbuffer(self, size, offsets, descrs):
         return VRawBufferInfo(size, offsets, descrs)
 
-    def make_vrawslice(self, offset):
+    def visit_vrawslice(self, offset):
         return VRawSliceInfo(offset)
 
-    def make_vstrplain(self, is_unicode=False):
+    def visit_vstrplain(self, is_unicode=False):
         if is_unicode:
             return VUniPlainInfo()
-        return VStrPlainInfo()
+        else:
+            return VStrPlainInfo()
 
-    def make_vstrconcat(self, is_unicode=False):
+    def visit_vstrconcat(self, is_unicode=False):
         if is_unicode:
             return VUniConcatInfo()
-        return VStrConcatInfo()
+        else:
+            return VStrConcatInfo()
 
-    def make_vstrslice(self, is_unicode=False):
+    def visit_vstrslice(self, is_unicode=False):
         if is_unicode:
             return VUniSliceInfo()
-        return VStrSliceInfo()
+        else:
+            return VStrSliceInfo()
 
     def register_virtual_fields(self, virtualbox, fieldboxes):
         tagged = self.liveboxes_from_env.get(virtualbox, UNASSIGNEDVIRTUAL)
@@ -352,13 +372,13 @@
             else:
                 assert tagbits == TAGVIRTUAL
                 value = optimizer.getvalue(box)
-                value.get_args_for_fail(self)
+                value.visitor_walk_recursive(self)
 
         for _, box, fieldbox, _ in pending_setfields:
             self.register_box(box)
             self.register_box(fieldbox)
             value = optimizer.getvalue(fieldbox)
-            value.get_args_for_fail(self)
+            value.visitor_walk_recursive(self)
 
         self._number_virtuals(liveboxes, optimizer, v)
         self._add_pending_fields(pending_setfields)
@@ -410,7 +430,7 @@
                 value = optimizer.getvalue(virtualbox)
                 fieldnums = [self._gettagged(box)
                              for box in fieldboxes]
-                vinfo = value.make_virtual_info(self, fieldnums)
+                vinfo = self.make_virtual_info(value, fieldnums)
                 # if a new vinfo instance is made, we get the fieldnums list we
                 # pass in as an attribute. hackish.
                 if vinfo.fieldnums is not fieldnums:
diff --git a/rpython/jit/metainterp/test/test_resume.py 
b/rpython/jit/metainterp/test/test_resume.py
--- a/rpython/jit/metainterp/test/test_resume.py
+++ b/rpython/jit/metainterp/test/test_resume.py
@@ -4,7 +4,7 @@
 from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
 from rpython.jit.metainterp.optimizeopt.optimizer import OptValue
 from rpython.jit.metainterp.optimizeopt.virtualize import VirtualValue, 
VArrayValue
-from rpython.jit.metainterp.optimizeopt.virtualize import VStructValue
+from rpython.jit.metainterp.optimizeopt.virtualize import VStructValue, 
AbstractVirtualValue
 from rpython.jit.metainterp.resume import *
 from rpython.jit.metainterp.history import BoxInt, BoxPtr, ConstInt
 from rpython.jit.metainterp.history import ConstPtr, ConstFloat
@@ -66,6 +66,26 @@
     assert v1.equals([1, 2, 4])
     assert not v1.equals([1, 2, 6])
 
+def test_reuse_vinfo():
+    class FakeVInfo(object):
+        def set_content(self, fieldnums):
+            self.fieldnums = fieldnums
+        def equals(self, fieldnums):
+            return self.fieldnums == fieldnums
+    class FakeVirtualValue(AbstractVirtualValue):
+        def visitor_dispatch_virtual_type(self, *args):
+            return FakeVInfo()
+    modifier = ResumeDataVirtualAdder(None, None)
+    v1 = FakeVirtualValue(None, None)
+    vinfo1 = modifier.make_virtual_info(v1, [1, 2, 4])
+    vinfo2 = modifier.make_virtual_info(v1, [1, 2, 4])
+    assert vinfo1 is vinfo2
+    vinfo3 = modifier.make_virtual_info(v1, [1, 2, 6])
+    assert vinfo3 is not vinfo2
+    vinfo4 = modifier.make_virtual_info(v1, [1, 2, 6])
+    assert vinfo3 is vinfo4
+
+
 class MyMetaInterp:
     _already_allocated_resume_virtuals = None
     callinfocollection = None
diff --git a/rpython/jit/metainterp/walkvirtual.py 
b/rpython/jit/metainterp/walkvirtual.py
new file mode 100644
--- /dev/null
+++ b/rpython/jit/metainterp/walkvirtual.py
@@ -0,0 +1,39 @@
+# this is some common infrastructure for code that needs to walk all virtuals
+# at a specific instruction. It is used by resume and unroll.
+
+class VirtualVisitor(object):
+    def visit_not_virtual(self, value):
+        raise NotImplementedError("abstract base class")
+
+    def visit_virtual(self, known_class, fielddescrs):
+        raise NotImplementedError("abstract base class")
+
+    def visit_vstruct(self, typedescr, fielddescrs):
+        raise NotImplementedError("abstract base class")
+
+    def visit_varray(self, arraydescr):
+        raise NotImplementedError("abstract base class")
+
+    def visit_varraystruct(self, arraydescr, fielddescrs):
+        raise NotImplementedError("abstract base class")
+
+    def visit_vrawbuffer(self, size, offsets, descrs):
+        raise NotImplementedError("abstract base class")
+
+    def visit_vrawslice(self, offset):
+        raise NotImplementedError("abstract base class")
+
+    def visit_vstrplain(self, is_unicode=False):
+        raise NotImplementedError("abstract base class")
+
+    def visit_vstrconcat(self, is_unicode=False):
+        raise NotImplementedError("abstract base class")
+
+    def visit_vstrslice(self, is_unicode=False):
+        raise NotImplementedError("abstract base class")
+
+    def register_virtual_fields(self, virtualbox, fieldboxes):
+        raise NotImplementedError("abstract base class")
+
+    def already_seen_virtual(self, virtualbox):
+        raise NotImplementedError("abstract base class")
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to