[pypy-commit] pypy optresult: (fijal, arigo) hack enough on VirtualInfo to make the first test allocating

fijal noreply at buildbot.pypy.org
Fri Feb 27 15:40:48 CET 2015


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: optresult
Changeset: r76162:7430103dc792
Date: 2015-02-27 16:39 +0200
http://bitbucket.org/pypy/pypy/changeset/7430103dc792/

Log:	(fijal, arigo) hack enough on VirtualInfo to make the first test
	allocating NEW_WITH_VTABLE pass

diff --git a/rpython/jit/metainterp/optimizeopt/generalize.py b/rpython/jit/metainterp/optimizeopt/generalize.py
--- a/rpython/jit/metainterp/optimizeopt/generalize.py
+++ b/rpython/jit/metainterp/optimizeopt/generalize.py
@@ -1,4 +1,4 @@
-from rpython.jit.metainterp.optimizeopt.optimizer import MININT, MAXINT
+#from rpython.jit.metainterp.optimizeopt.optimizer import MININT, MAXINT
 
 
 class GeneralizationStrategy(object):
diff --git a/rpython/jit/metainterp/optimizeopt/heap.py b/rpython/jit/metainterp/optimizeopt/heap.py
--- a/rpython/jit/metainterp/optimizeopt/heap.py
+++ b/rpython/jit/metainterp/optimizeopt/heap.py
@@ -4,8 +4,9 @@
 from rpython.jit.metainterp.optimizeopt.util import args_dict
 from rpython.jit.metainterp.history import Const, ConstInt
 from rpython.jit.metainterp.jitexc import JitException
-from rpython.jit.metainterp.optimizeopt.optimizer import Optimization,\
-     MODE_ARRAY, LEVEL_KNOWNCLASS, REMOVED
+from rpython.jit.metainterp.optimizeopt.optimizer import Optimization, REMOVED
+from rpython.jit.metainterp.optimizeopt.info import MODE_ARRAY,\
+     LEVEL_KNOWNCLASS
 from rpython.jit.metainterp.optimizeopt.util import make_dispatcher_method
 from rpython.jit.metainterp.optimizeopt.intutils import IntBound
 from rpython.jit.metainterp.optimize import InvalidLoop
diff --git a/rpython/jit/metainterp/optimizeopt/info.py b/rpython/jit/metainterp/optimizeopt/info.py
new file mode 100644
--- /dev/null
+++ b/rpython/jit/metainterp/optimizeopt/info.py
@@ -0,0 +1,139 @@
+
+from rpython.jit.metainterp.resoperation import AbstractValue
+
+""" The tag field on PtrOptInfo has a following meaning:
+
+lower two bits are LEVEL
+"""
+
+LEVEL_UNKNOWN    = 0
+LEVEL_NONNULL    = 1
+LEVEL_KNOWNCLASS = 2     # might also mean KNOWNARRAYDESCR, for arrays
+LEVEL_CONSTANT   = 3
+
+MODE_ARRAY   = '\x00'
+MODE_STR     = '\x01'
+MODE_UNICODE = '\x02'
+
+class AbstractInfo(AbstractValue):
+    is_info_class = True
+
+    def force_box(self, op, optforce):
+        return op
+
+class PtrOptInfo(AbstractInfo):
+    _attrs_ = ('_tag', 'known_class', 'last_guard_pos', 'lenbound')
+    is_info_class = True
+
+    _tag = 0
+    known_class = None
+    last_guard_pos = -1
+    lenbound = None
+
+    #def __init__(self, level=None, known_class=None, intbound=None):
+    #    OptValue.__init__(self, box, level, None, intbound)
+    #    if not isinstance(box, Const):
+    #        self.known_class = known_class
+
+    def getlevel(self):
+        return self._tag & 0x3
+
+    def setlevel(self, level):
+        self._tag = (self._tag & (~0x3)) | level
+
+    def __repr__(self):
+        level = {LEVEL_UNKNOWN: 'UNKNOWN',
+                 LEVEL_NONNULL: 'NONNULL',
+                 LEVEL_KNOWNCLASS: 'KNOWNCLASS',
+                 LEVEL_CONSTANT: 'CONSTANT'}.get(self.getlevel(),
+                                                 self.getlevel())
+        return '<%s %s %s>' % (
+            self.__class__.__name__,
+            level,
+            self.box)
+
+    def make_len_gt(self, mode, descr, val):
+        if self.lenbound:
+            if self.lenbound.mode != mode or self.lenbound.descr != descr:
+                # XXX a rare case?  it seems to occur sometimes when
+                # running lib-python's test_io.py in PyPy on Linux 32...
+                from rpython.jit.metainterp.optimize import InvalidLoop
+                raise InvalidLoop("bad mode/descr")
+            self.lenbound.bound.make_gt(IntBound(val, val))
+        else:
+            self.lenbound = LenBound(mode, descr, IntLowerBound(val + 1))
+
+    def make_nonnull(self, optimizer):
+        assert self.getlevel() < LEVEL_NONNULL
+        self.setlevel(LEVEL_NONNULL)
+        if optimizer is not None:
+            self.last_guard_pos = len(optimizer._newoperations) - 1
+            assert self.get_last_guard(optimizer).is_guard()
+
+    def make_constant_class(self, optimizer, classbox):
+        assert self.getlevel() < LEVEL_KNOWNCLASS
+        self.known_class = classbox
+        self.setlevel(LEVEL_KNOWNCLASS)
+        if optimizer is not None:
+            self.last_guard_pos = len(optimizer._newoperations) - 1
+            assert self.get_last_guard(optimizer).is_guard()
+
+    def import_from(self, other, optimizer):
+        OptValue.import_from(self, other, optimizer)
+        if self.getlevel() != LEVEL_CONSTANT:
+            if other.getlenbound():
+                if self.lenbound:
+                    assert other.getlenbound().mode == self.lenbound.mode
+                    assert other.getlenbound().descr == self.lenbound.descr
+                    self.lenbound.bound.intersect(other.getlenbound().bound)
+                else:
+                    self.lenbound = other.getlenbound().clone()
+
+    def make_guards(self, box):
+        guards = []
+        level = self.getlevel()
+        if level == LEVEL_CONSTANT:
+            op = ResOperation(rop.GUARD_VALUE, [box, self.box], None)
+            guards.append(op)
+        elif level == LEVEL_KNOWNCLASS:
+            op = ResOperation(rop.GUARD_NONNULL_CLASS,
+                              [box, self.known_class], None)
+            guards.append(op)
+        else:
+            if level == LEVEL_NONNULL:
+                op = ResOperation(rop.GUARD_NONNULL, [box], None)
+                guards.append(op)
+            if self.lenbound:
+                lenbox = BoxInt()
+                if self.lenbound.mode == MODE_ARRAY:
+                    op = ResOperation(rop.ARRAYLEN_GC, [box], lenbox, self.lenbound.descr)
+                elif self.lenbound.mode == MODE_STR:
+                    op = ResOperation(rop.STRLEN, [box], lenbox, self.lenbound.descr)
+                elif self.lenbound.mode == MODE_UNICODE:
+                    op = ResOperation(rop.UNICODELEN, [box], lenbox, self.lenbound.descr)
+                else:
+                    debug_print("Unknown lenbound mode")
+                    assert False
+                guards.append(op)
+                self.lenbound.bound.make_guards(lenbox, guards)
+        return guards
+
+    def get_constant_class(self, cpu):
+        level = self.getlevel()
+        if level == LEVEL_KNOWNCLASS:
+            return self.known_class
+        elif level == LEVEL_CONSTANT and not self.is_null():
+            return cpu.ts.cls_of_box(self.box)
+        else:
+            return None
+
+    def getlenbound(self):
+        return self.lenbound
+
+    def get_last_guard(self, optimizer):
+        if self.last_guard_pos == -1:
+            return None
+        return optimizer._newoperations[self.last_guard_pos]
+
+    def get_known_class(self):
+        return self.known_class
diff --git a/rpython/jit/metainterp/optimizeopt/intbounds.py b/rpython/jit/metainterp/optimizeopt/intbounds.py
--- a/rpython/jit/metainterp/optimizeopt/intbounds.py
+++ b/rpython/jit/metainterp/optimizeopt/intbounds.py
@@ -1,13 +1,14 @@
 import sys
 from rpython.jit.metainterp.history import ConstInt
 from rpython.jit.metainterp.optimize import InvalidLoop
-from rpython.jit.metainterp.optimizeopt.intutils import (IntBound, IntLowerBound,
-    IntUpperBound)
+from rpython.jit.metainterp.optimizeopt.intutils import (IntBound,
+    IntLowerBound, IntUpperBound)
 from rpython.jit.metainterp.optimizeopt.optimizer import (Optimization, CONST_1,
-    CONST_0, MODE_ARRAY, MODE_STR, MODE_UNICODE)
+    CONST_0)
+from rpython.jit.metainterp.optimizeopt.info import MODE_ARRAY, MODE_STR,\
+     MODE_UNICODE
 from rpython.jit.metainterp.optimizeopt.util import make_dispatcher_method
 from rpython.jit.metainterp.resoperation import rop, AbstractResOp
-from rpython.jit.backend.llsupport import symbolic
 
 
 def get_integer_min(is_unsigned, byte_size):
diff --git a/rpython/jit/metainterp/optimizeopt/intutils.py b/rpython/jit/metainterp/optimizeopt/intutils.py
--- a/rpython/jit/metainterp/optimizeopt/intutils.py
+++ b/rpython/jit/metainterp/optimizeopt/intutils.py
@@ -1,15 +1,16 @@
 from rpython.rlib.rarithmetic import ovfcheck, LONG_BIT, maxint, is_valid_int
 from rpython.rlib.objectmodel import we_are_translated
-from rpython.jit.metainterp.resoperation import rop, ResOperation, AbstractValue
+from rpython.jit.metainterp.resoperation import rop, ResOperation
+from rpython.jit.metainterp.optimizeopt.info import AbstractInfo
 from rpython.jit.metainterp.history import ConstInt
 
+
 MAXINT = maxint
 MININT = -maxint - 1
 
 
-class IntBound(AbstractValue):
+class IntBound(AbstractInfo):
     _attrs_ = ('has_upper', 'has_lower', 'upper', 'lower')
-    is_info_class = True
 
     def __init__(self, lower, upper):
         self.has_upper = True
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
@@ -3,30 +3,13 @@
 from rpython.jit.metainterp.logger import LogOperations
 from rpython.jit.metainterp.history import Const, ConstInt, REF, ConstPtr
 from rpython.jit.metainterp.optimizeopt.intutils import IntBound,\
-     IntLowerBound, MININT, MAXINT, IntUnbounded, ConstIntBound
+     IntUnbounded, ConstIntBound
 from rpython.jit.metainterp.optimizeopt.util import make_dispatcher_method
-from rpython.jit.metainterp.resoperation import rop, ResOperation,\
-     AbstractResOp, AbstractInputArg, GuardResOp, AbstractValue
+from rpython.jit.metainterp.resoperation import rop, AbstractResOp, GuardResOp
+from rpython.jit.metainterp.optimizeopt.info import PtrOptInfo
 from rpython.jit.metainterp.typesystem import llhelper
-from rpython.tool.pairtype import extendabletype
-from rpython.rlib.debug import debug_print
 from rpython.rlib.objectmodel import specialize, we_are_translated
 
-""" The tag field on OptValue has a following meaning:
-
-lower two bits are LEVEL
-next 16 bits is the position in the original list, 0 if unknown or a constant
-"""
-
-LEVEL_UNKNOWN    = 0
-LEVEL_NONNULL    = 1
-LEVEL_KNOWNCLASS = 2     # might also mean KNOWNARRAYDESCR, for arrays
-LEVEL_CONSTANT   = 3
-
-MODE_ARRAY   = '\x00'
-MODE_STR     = '\x01'
-MODE_UNICODE = '\x02'
-
 
 class LenBound(object):
     def __init__(self, mode, descr, bound):
@@ -196,131 +179,6 @@
 ##         return None
 
 
-class PtrOptInfo(AbstractValue):
-    _attrs_ = ('_tag', 'known_class', 'last_guard_pos', 'lenbound')
-    is_info_class = True
-
-    _tag = 0
-    known_class = None
-    last_guard_pos = -1
-    lenbound = None
-
-    #def __init__(self, level=None, known_class=None, intbound=None):
-    #    OptValue.__init__(self, box, level, None, intbound)
-    #    if not isinstance(box, Const):
-    #        self.known_class = known_class
-
-    def getlevel(self):
-        return self._tag & 0x3
-
-    def setlevel(self, level):
-        self._tag = (self._tag & (~0x3)) | level
-
-    def __repr__(self):
-        level = {LEVEL_UNKNOWN: 'UNKNOWN',
-                 LEVEL_NONNULL: 'NONNULL',
-                 LEVEL_KNOWNCLASS: 'KNOWNCLASS',
-                 LEVEL_CONSTANT: 'CONSTANT'}.get(self.getlevel(),
-                                                 self.getlevel())
-        return '<%s %s %s>' % (
-            self.__class__.__name__,
-            level,
-            self.box)
-
-    def copy_from(self, other_value):
-        assert isinstance(other_value, PtrOptValue)
-        self.box = other_value.box
-        self.known_class = other_value.known_class
-        self._tag = other_value._tag
-        self.last_guard_pos = other_value.last_guard_pos
-        self.lenbound = other_value.lenbound
-
-    def make_len_gt(self, mode, descr, val):
-        if self.lenbound:
-            if self.lenbound.mode != mode or self.lenbound.descr != descr:
-                # XXX a rare case?  it seems to occur sometimes when
-                # running lib-python's test_io.py in PyPy on Linux 32...
-                from rpython.jit.metainterp.optimize import InvalidLoop
-                raise InvalidLoop("bad mode/descr")
-            self.lenbound.bound.make_gt(IntBound(val, val))
-        else:
-            self.lenbound = LenBound(mode, descr, IntLowerBound(val + 1))
-
-    def make_nonnull(self, optimizer):
-        assert self.getlevel() < LEVEL_NONNULL
-        self.setlevel(LEVEL_NONNULL)
-        if optimizer is not None:
-            self.last_guard_pos = len(optimizer._newoperations) - 1
-            assert self.get_last_guard(optimizer).is_guard()
-
-    def make_constant_class(self, optimizer, classbox):
-        assert self.getlevel() < LEVEL_KNOWNCLASS
-        self.known_class = classbox
-        self.setlevel(LEVEL_KNOWNCLASS)
-        if optimizer is not None:
-            self.last_guard_pos = len(optimizer._newoperations) - 1
-            assert self.get_last_guard(optimizer).is_guard()
-
-    def import_from(self, other, optimizer):
-        OptValue.import_from(self, other, optimizer)
-        if self.getlevel() != LEVEL_CONSTANT:
-            if other.getlenbound():
-                if self.lenbound:
-                    assert other.getlenbound().mode == self.lenbound.mode
-                    assert other.getlenbound().descr == self.lenbound.descr
-                    self.lenbound.bound.intersect(other.getlenbound().bound)
-                else:
-                    self.lenbound = other.getlenbound().clone()
-
-    def make_guards(self, box):
-        guards = []
-        level = self.getlevel()
-        if level == LEVEL_CONSTANT:
-            op = ResOperation(rop.GUARD_VALUE, [box, self.box], None)
-            guards.append(op)
-        elif level == LEVEL_KNOWNCLASS:
-            op = ResOperation(rop.GUARD_NONNULL_CLASS,
-                              [box, self.known_class], None)
-            guards.append(op)
-        else:
-            if level == LEVEL_NONNULL:
-                op = ResOperation(rop.GUARD_NONNULL, [box], None)
-                guards.append(op)
-            if self.lenbound:
-                lenbox = BoxInt()
-                if self.lenbound.mode == MODE_ARRAY:
-                    op = ResOperation(rop.ARRAYLEN_GC, [box], lenbox, self.lenbound.descr)
-                elif self.lenbound.mode == MODE_STR:
-                    op = ResOperation(rop.STRLEN, [box], lenbox, self.lenbound.descr)
-                elif self.lenbound.mode == MODE_UNICODE:
-                    op = ResOperation(rop.UNICODELEN, [box], lenbox, self.lenbound.descr)
-                else:
-                    debug_print("Unknown lenbound mode")
-                    assert False
-                guards.append(op)
-                self.lenbound.bound.make_guards(lenbox, guards)
-        return guards
-
-    def get_constant_class(self, cpu):
-        level = self.getlevel()
-        if level == LEVEL_KNOWNCLASS:
-            return self.known_class
-        elif level == LEVEL_CONSTANT and not self.is_null():
-            return cpu.ts.cls_of_box(self.box)
-        else:
-            return None
-
-    def getlenbound(self):
-        return self.lenbound
-
-    def get_last_guard(self, optimizer):
-        if self.last_guard_pos == -1:
-            return None
-        return optimizer._newoperations[self.last_guard_pos]
-
-    def get_known_class(self):
-        return self.known_class
-
 ## class IntOptInfo(OptInfo):
 ##     _attrs_ = ('intbound',)
 
@@ -641,7 +499,11 @@
         return op
 
     def force_box(self, op):
-        return self.get_box_replacement(op)
+        op = self.get_box_replacement(op)
+        info = op.get_forwarded()
+        if info is not None:
+            return info.force_box(op, self)
+        return op
 
     def ensure_imported(self, value):
         pass
diff --git a/rpython/jit/metainterp/optimizeopt/rewrite.py b/rpython/jit/metainterp/optimizeopt/rewrite.py
--- a/rpython/jit/metainterp/optimizeopt/rewrite.py
+++ b/rpython/jit/metainterp/optimizeopt/rewrite.py
@@ -6,7 +6,8 @@
 from rpython.jit.metainterp.optimize import InvalidLoop
 from rpython.jit.metainterp.optimizeopt.intutils import IntBound
 from rpython.jit.metainterp.optimizeopt.optimizer import (Optimization, REMOVED,
-    CONST_0, CONST_1, PtrOptInfo, INFO_NONNULL, INFO_NULL)
+    CONST_0, CONST_1, INFO_NONNULL, INFO_NULL)
+from rpython.jit.metainterp.optimizeopt.info import PtrOptInfo
 from rpython.jit.metainterp.optimizeopt.util import _findall, make_dispatcher_method
 from rpython.jit.metainterp.resoperation import rop, ResOperation, opclasses,\
      OpHelpers
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
@@ -3,7 +3,7 @@
 from rpython.jit.codewriter.heaptracker import vtable2descr
 from rpython.jit.metainterp.history import Const, ConstInt, BoxInt
 from rpython.jit.metainterp.history import CONST_NULL, BoxPtr
-from rpython.jit.metainterp.optimizeopt import optimizer
+from rpython.jit.metainterp.optimizeopt import info, optimizer
 from rpython.jit.metainterp.optimizeopt.optimizer import REMOVED
 from rpython.jit.metainterp.optimizeopt.util import (make_dispatcher_method,
                                                      descrlist_dict, sort_descrs)
@@ -13,9 +13,9 @@
 from rpython.rlib.objectmodel import we_are_translated, specialize
 from rpython.jit.metainterp.optimizeopt.intutils import IntUnbounded
 
-class AbstractVirtualInfo(optimizer.PtrOptInfo):
+class AbstractVirtualInfo(info.PtrOptInfo):
     _attrs_ = ('_cached_vinfo',)
-    _tag = optimizer.LEVEL_NONNULL
+    _tag = info.LEVEL_NONNULL
     is_about_raw = False
     _cached_vinfo = None
 
@@ -23,12 +23,20 @@
         xxx
         return self.box is not None
 
-    def force_box(self, optforce):
-        xxxx
-        if self.box is None:
-            optforce.forget_numberings(self.source_op)
-            self._really_force(optforce)
-        return self.box
+    def force_box(self, op, optforce):
+        op.set_forwarded(None)
+        optforce.emit_operation(op)
+        newop = optforce.getlastop()
+        op.set_forwarded(newop)
+        optforce.getptrinfo(newop).make_constant_class(None, self.known_class)
+        return newop
+    
+    #def force_box(self, optforce):
+    #    xxxx
+    #    if self.box is None:
+    #        optforce.forget_numberings(self.source_op)
+    #        self._really_force(optforce)
+    #    return self.box
 
     def force_at_end_of_preamble(self, already_forced, optforce):
         xxxx
@@ -65,13 +73,11 @@
 get_fielddescrlist_cache._annspecialcase_ = "specialize:memo"
 
 class AbstractVirtualStructInfo(AbstractVirtualInfo):
-    _attrs_ = ('_fields', '_cached_sorted_fields')
+    _attrs_ = ('_fields',)
 
-    def __init__(self, cpu):
+    def __init__(self):
         AbstractVirtualInfo.__init__(self)
-        self.cpu = cpu
-        self._fields = {}
-        self._cached_sorted_fields = None
+        #self._fields = {}
 
     def getfield(self, ofs, default):
         return self._fields.get(ofs, default)
@@ -190,12 +196,13 @@
             fieldvalue.visitor_walk_recursive(visitor)
 
 class VirtualInfo(AbstractVirtualStructInfo):
-    _tag = optimizer.LEVEL_KNOWNCLASS
+    _tag = info.LEVEL_KNOWNCLASS
 
-    def __init__(self, known_class):
+    def __init__(self, known_class, descr):
         AbstractVirtualStructInfo.__init__(self)
         assert isinstance(known_class, Const)
         self.known_class = known_class
+        self.descr = descr
 
     @specialize.argtype(1)
     def _visitor_dispatch_virtual_type(self, visitor):
@@ -215,6 +222,7 @@
 class VStructInfo(AbstractVirtualStructInfo):
 
     def __init__(self, cpu, structdescr, source_op):
+        xxx
         AbstractVirtualStructValue.__init__(self, cpu, source_op)
         self.structdescr = structdescr
 
@@ -522,11 +530,10 @@
 
     _last_guard_not_forced_2 = None
 
-    def make_virtual(self, known_class, source_op):
-        xxx
-        vvalue = VirtualValue(self.optimizer.cpu, known_class, source_op)
-        self.make_equal_to(source_op, vvalue)
-        return vvalue
+    def make_virtual(self, known_class, source_op, descr):
+        info = VirtualInfo(known_class, descr)
+        source_op.set_forwarded(info)
+        return info
 
     def make_varray(self, arraydescr, size, source_op, clear=False):
         if arraydescr.is_array_of_structs():
@@ -703,7 +710,7 @@
             self.emit_operation(op)
 
     def optimize_NEW_WITH_VTABLE(self, op):
-        self.make_virtual(op.getarg(0), op)
+        self.make_virtual(op.getarg(0), op, op.getdescr())
 
     def optimize_NEW(self, op):
         self.make_vstruct(op.getdescr(), op)
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
@@ -3,7 +3,7 @@
         ConstPtr, ConstFloat)
 from rpython.jit.metainterp.optimizeopt import virtualize
 from rpython.jit.metainterp.optimizeopt.intutils import IntUnbounded
-from rpython.jit.metainterp.optimizeopt.optimizer import (LEVEL_CONSTANT,
+from rpython.jit.metainterp.optimizeopt.info import (LEVEL_CONSTANT,
     LEVEL_KNOWNCLASS, LEVEL_NONNULL, LEVEL_UNKNOWN)
 from rpython.jit.metainterp.resoperation import rop, ResOperation,\
      AbstractInputArg


More information about the pypy-commit mailing list