[pypy-commit] pypy optresult: basic virtuals

fijal noreply at buildbot.pypy.org
Sat Mar 7 13:17:03 CET 2015


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: optresult
Changeset: r76269:917cc4c8ef85
Date: 2015-03-07 14:05 +0200
http://bitbucket.org/pypy/pypy/changeset/917cc4c8ef85/

Log:	basic virtuals

diff --git a/rpython/jit/backend/llgraph/runner.py b/rpython/jit/backend/llgraph/runner.py
--- a/rpython/jit/backend/llgraph/runner.py
+++ b/rpython/jit/backend/llgraph/runner.py
@@ -89,8 +89,10 @@
         return getkind(self.RESULT)[0]
 
 class SizeDescr(AbstractDescr):
-    def __init__(self, S):
+    def __init__(self, S, runner):
         self.S = S
+        self.all_fielddescrs = heaptracker.all_fielddescrs(runner, S,
+                                    get_field_descr=LLGraphCPU.fielddescrof)
 
     def as_vtable_size_descr(self):
         return self
@@ -106,6 +108,7 @@
         self.S = S
         self.fieldname = fieldname
         self.FIELD = getattr(S, fieldname)
+        self.index = heaptracker.get_fielddescr_index_in(S, fieldname)
 
     def get_vinfo(self):
         return self.vinfo
@@ -374,7 +377,7 @@
         try:
             return self.descrs[key]
         except KeyError:
-            descr = SizeDescr(S)
+            descr = SizeDescr(S, self)
             self.descrs[key] = descr
             return descr
 
diff --git a/rpython/jit/backend/llsupport/descr.py b/rpython/jit/backend/llsupport/descr.py
--- a/rpython/jit/backend/llsupport/descr.py
+++ b/rpython/jit/backend/llsupport/descr.py
@@ -36,10 +36,11 @@
     tid = llop.combine_ushort(lltype.Signed, 0, 0)
 
     def __init__(self, size, count_fields_if_immut=-1,
-                 gc_fielddescrs=None):
+                 gc_fielddescrs=None, all_fielddescrs=None):
         self.size = size
         self.count_fields_if_immut = count_fields_if_immut
         self.gc_fielddescrs = gc_fielddescrs
+        self.all_fielddescrs = all_fielddescrs
 
     def count_fields_if_immutable(self):
         return self.count_fields_if_immut
@@ -61,12 +62,13 @@
         size = symbolic.get_size(STRUCT, gccache.translate_support_code)
         count_fields_if_immut = heaptracker.count_fields_if_immutable(STRUCT)
         gc_fielddescrs = heaptracker.gc_fielddescrs(gccache, STRUCT)
+        all_fielddescrs = heaptracker.all_fielddescrs(gccache, STRUCT)
         if heaptracker.has_gcstruct_a_vtable(STRUCT):
             sizedescr = SizeDescrWithVTable(size, count_fields_if_immut,
-                                            gc_fielddescrs)
+                                            gc_fielddescrs, all_fielddescrs)
         else:
             sizedescr = SizeDescr(size, count_fields_if_immut,
-                                  gc_fielddescrs)
+                                  gc_fielddescrs, all_fielddescrs)
         gccache.init_size_descr(STRUCT, sizedescr)
         cache[STRUCT] = sizedescr
         return sizedescr
diff --git a/rpython/jit/codewriter/heaptracker.py b/rpython/jit/codewriter/heaptracker.py
--- a/rpython/jit/codewriter/heaptracker.py
+++ b/rpython/jit/codewriter/heaptracker.py
@@ -136,9 +136,12 @@
     vtable = llmemory.cast_ptr_to_adr(vtable)
     return adr2int(vtable)
 
-def fielddescrs_from_struct(gccache, STRUCT, only_gc=False, res=None):
+def all_fielddescrs(gccache, STRUCT, only_gc=False, res=None,
+                    get_field_descr=None):
     from rpython.jit.backend.llsupport import descr
 
+    if get_field_descr is None:
+        get_field_descr = descr.get_field_descr
     if res is None:
         res = []
     # order is not relevant, except for tests
@@ -146,11 +149,31 @@
         FIELD = getattr(STRUCT, name)
         if FIELD is lltype.Void:
             continue
+        if name == 'typeptr':
+            continue # dealt otherwise
         elif isinstance(FIELD, lltype.Struct):
-            fielddescrs_from_struct(gccache, FIELD, only_gc, res)
+            all_fielddescrs(gccache, FIELD, only_gc, res, get_field_descr)
         elif (not only_gc) or (isinstance(FIELD, lltype.Ptr) and FIELD._needsgc()):
-            res.append(descr.get_field_descr(gccache, STRUCT, name))
+            res.append(get_field_descr(gccache, STRUCT, name))
     return res
 
 def gc_fielddescrs(gccache, STRUCT):
-    return fielddescrs_from_struct(gccache, STRUCT, True)
+    return all_fielddescrs(gccache, STRUCT, True)
+
+def get_fielddescr_index_in(STRUCT, fieldname, cur_index=0):
+    for name in STRUCT._names:
+        FIELD = getattr(STRUCT, name)
+        if FIELD is lltype.Void:
+            continue
+        if name == 'typeptr':
+            continue # dealt otherwise
+        elif isinstance(FIELD, lltype.Struct):
+            r = get_fielddescr_index_in(FIELD, fieldname, cur_index)
+            if r != -1:
+                return r
+            continue
+        elif name == fieldname:
+            return cur_index
+        cur_index += 1
+    return -1 # not found
+    
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
@@ -478,6 +478,8 @@
         return pendingfields
 
     def optimize_GETFIELD_GC_I(self, op):
+        self.emit_operation(op)
+        return
         structvalue = self.getvalue(op.getarg(0))
         cf = self.field_cache(op.getdescr())
         fieldvalue = cf.getfield_from_cache(self, structvalue)
diff --git a/rpython/jit/metainterp/optimizeopt/info.py b/rpython/jit/metainterp/optimizeopt/info.py
--- a/rpython/jit/metainterp/optimizeopt/info.py
+++ b/rpython/jit/metainterp/optimizeopt/info.py
@@ -1,5 +1,6 @@
 
-from rpython.jit.metainterp.resoperation import AbstractValue
+from rpython.jit.metainterp.resoperation import AbstractValue, ResOperation,\
+     rop
 
 """ The tag field on PtrOptInfo has a following meaning:
 
@@ -52,14 +53,9 @@
     def is_nonnull(self):
         return True
 
-    
-class InstancePtrInfo(NonNullPtrInfo):
-    _attrs_ = ('_known_class', '_is_virtual', '_fields')
-    _fields = None
 
-    def __init__(self, known_class=None, is_virtual=False):
-        self._known_class = known_class
-        self._is_virtual = is_virtual
+class AbstractStructPtrInfo(NonNullPtrInfo):
+    _attrs_ = ('_is_virtual', '_fields')
 
     def force_box(self, op, optforce):
         if self._is_virtual:
@@ -69,20 +65,38 @@
             op.set_forwarded(newop)
             newop.set_forwarded(self)
             self._is_virtual = False
+            if self._fields is not None:
+                descr = op.getdescr()
+                for i, flddescr in enumerate(descr.all_fielddescrs):
+                    fld = self._fields[i]
+                    if fld is not None:
+                        subbox = optforce.force_box(fld)
+                        op = ResOperation(rop.SETFIELD_GC, [op, subbox],
+                                          descr=flddescr)
+                        optforce.emit_operation(op)
             return newop
         return op
 
+    def init_fields(self, descr):
+        self._fields = [None] * len(descr.all_fielddescrs)
+
     def setfield_virtual(self, descr, op):
-        if self._fields is None:
-            self._fields = {}
-        self._fields[descr] = op
+        self._fields[descr.index] = op
 
     def getfield_virtual(self, descr):
-        return self._fields.get(descr, None)
+        return self._fields[descr.index]
 
     def is_virtual(self):
         return self._is_virtual
 
+class InstancePtrInfo(AbstractStructPtrInfo):
+    _attrs_ = ('_known_class')
+    _fields = None
+
+    def __init__(self, known_class=None, is_virtual=False):
+        self._known_class = known_class
+        self._is_virtual = is_virtual
+
     def get_known_class(self, cpu):
         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
@@ -441,12 +441,12 @@
             self.propagate_bounds_backward(box2)
 
     def make_int_le(self, box1, box2):
-        v1 = self.getvalue(box1)
-        v2 = self.getvalue(box2)
-        if v1.getintbound().make_le(v2.getintbound()):
-            self.propagate_bounds_backward(box1, v1)
-        if v2.getintbound().make_ge(v1.getintbound()):
-            self.propagate_bounds_backward(box2, v2)
+        b1 = self.getintbound(box1)
+        b2 = self.getintbound(box2)
+        if b1.make_le(b2):
+            self.propagate_bounds_backward(box1)
+        if b2.make_ge(b1):
+            self.propagate_bounds_backward(box2)
 
     def make_int_gt(self, box1, box2):
         self.make_int_lt(box2, box1)
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
@@ -199,14 +199,14 @@
     def test_remove_guard_class_2(self):
         ops = """
         [i0]
-        p0 = new_with_vtable(ConstClass(node_vtable))
+        p0 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
         escape_n(p0)
         guard_class(p0, ConstClass(node_vtable)) []
         jump(i0)
         """
         expected = """
         [i0]
-        p0 = new_with_vtable(ConstClass(node_vtable))
+        p0 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
         escape_n(p0)
         jump(i0)
         """
@@ -426,7 +426,7 @@
     def test_ooisnull_oononnull_via_virtual(self):
         ops = """
         [p0]
-        pv = new_with_vtable(ConstClass(node_vtable))
+        pv = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
         setfield_gc(pv, p0, descr=valuedescr)
         guard_nonnull(p0) []
         p1 = getfield_gc_r(pv, descr=valuedescr)
@@ -575,7 +575,7 @@
         [i1, p2, p3]
         i3 = getfield_gc_i(p3, descr=valuedescr)
         escape_n(i3)
-        p1 = new_with_vtable(ConstClass(node_vtable))
+        p1 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
         setfield_gc(p1, i1, descr=valuedescr)
         jump(i1, p1, p2)
         """
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
@@ -524,6 +524,7 @@
 
     def make_virtual(self, known_class, source_op, descr):
         opinfo = info.InstancePtrInfo(known_class, is_virtual=True)
+        opinfo.init_fields(descr)
         source_op.set_forwarded(opinfo)
         return opinfo
 
@@ -682,8 +683,7 @@
                 fieldvalue = self.optimizer.new_const(op.getdescr())
             self.make_equal_to(op, fieldop)
         else:
-            yyyy
-            value.ensure_nonnull()
+            self.make_nonnull(op.getarg(0))
             self.emit_operation(op)
     optimize_GETFIELD_GC_R = optimize_GETFIELD_GC_I
     optimize_GETFIELD_GC_F = optimize_GETFIELD_GC_I
diff --git a/rpython/jit/metainterp/resoperation.py b/rpython/jit/metainterp/resoperation.py
--- a/rpython/jit/metainterp/resoperation.py
+++ b/rpython/jit/metainterp/resoperation.py
@@ -719,7 +719,7 @@
     'GETFIELD_RAW/1d/fi',
     '_MALLOC_FIRST',
     'NEW/0d/r',           #-> GcStruct, gcptrs inside are zeroed (not the rest)
-    'NEW_WITH_VTABLE/1/r',#-> GcStruct with vtable, gcptrs inside are zeroed
+    'NEW_WITH_VTABLE/1d/r',#-> GcStruct with vtable, gcptrs inside are zeroed
     'NEW_ARRAY/1d/r',     #-> GcArray, not zeroed. only for arrays of primitives
     'NEW_ARRAY_CLEAR/1d/r',#-> GcArray, fully zeroed
     'NEWSTR/1/r',         #-> STR, the hash field is zeroed


More information about the pypy-commit mailing list