Author: Maciej Fijalkowski <[email protected]>
Branch: optresult
Changeset: r76328:9b36048a749a
Date: 2015-03-11 17:05 +0200
http://bitbucket.org/pypy/pypy/changeset/9b36048a749a/
Log: make the fisrt heapcache test pass
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,11 +89,15 @@
return getkind(self.RESULT)[0]
class SizeDescr(AbstractDescr):
- def __init__(self, S, runner):
+ def __init__(self, S, is_object, runner):
self.S = S
+ self._is_object = is_object
self.all_fielddescrs = heaptracker.all_fielddescrs(runner, S,
get_field_descr=LLGraphCPU.fielddescrof)
+ def is_object(self):
+ return self._is_object
+
def as_vtable_size_descr(self):
return self
@@ -374,12 +378,12 @@
self.descrs[key] = descr
return descr
- def sizeof(self, S):
+ def sizeof(self, S, is_object):
key = ('size', S)
try:
return self.descrs[key]
except KeyError:
- descr = SizeDescr(S, self)
+ descr = SizeDescr(S, is_object, self)
self.descrs[key] = descr
return descr
@@ -390,6 +394,8 @@
except KeyError:
descr = FieldDescr(S, fieldname)
self.descrs[key] = descr
+ is_obj = heaptracker.has_gcstruct_a_vtable(S)
+ descr.parent_descr = self.sizeof(S, is_obj)
if self.vinfo_for_tests is not None:
descr.vinfo = self.vinfo_for_tests
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
@@ -48,10 +48,16 @@
def repr_of_descr(self):
return '<SizeDescr %s>' % self.size
+ def is_object(self):
+ return False
+
class SizeDescrWithVTable(SizeDescr):
def as_vtable_size_descr(self):
return self
+ def is_object(self):
+ return True
+
BaseSizeDescr = SizeDescr
def get_size_descr(gccache, STRUCT):
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
@@ -87,7 +87,7 @@
def register_known_gctype(cpu, vtable, STRUCT):
# register the correspondance 'vtable' <-> 'STRUCT' in the cpu
- sizedescr = cpu.sizeof(STRUCT)
+ sizedescr = cpu.sizeof(STRUCT, has_gcstruct_a_vtable(STRUCT))
assert sizedescr.as_vtable_size_descr() is sizedescr
try:
assert sizedescr._corresponding_vtable == vtable
diff --git a/rpython/jit/metainterp/optimizeopt/earlyforce.py
b/rpython/jit/metainterp/optimizeopt/earlyforce.py
--- a/rpython/jit/metainterp/optimizeopt/earlyforce.py
+++ b/rpython/jit/metainterp/optimizeopt/earlyforce.py
@@ -1,3 +1,4 @@
+
from rpython.jit.codewriter.effectinfo import EffectInfo
from rpython.jit.metainterp.optimizeopt.optimizer import Optimization
from rpython.jit.metainterp.resoperation import rop
@@ -14,8 +15,7 @@
def propagate_forward(self, op):
opnum = op.getopnum()
- if 0: # XXX
- if (opnum != rop.SETFIELD_GC and
+ if (opnum != rop.SETFIELD_GC and
opnum != rop.SETARRAYITEM_GC and
opnum != rop.SETARRAYITEM_RAW and
opnum != rop.QUASIIMMUT_FIELD and
@@ -26,9 +26,7 @@
not is_raw_free(op, opnum)):
for arg in op.getarglist():
- if arg in self.optimizer.values:
- value = self.getvalue(arg)
- value.force_box(self)
+ self.optimizer.force_box(arg)
self.emit_operation(op)
def setup(self):
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
@@ -5,8 +5,7 @@
from rpython.jit.metainterp.history import Const, ConstInt
from rpython.jit.metainterp.jitexc import JitException
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.info import MODE_ARRAY
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
@@ -30,6 +29,7 @@
# value pending in the ResOperation is *not* visible in
# 'cached_fields'.
#
+ Xxxx
self._cached_fields = {}
self._cached_fields_getfield_op = {}
self._lazy_setfield = None
@@ -186,8 +186,8 @@
"""Cache repeated heap accesses"""
def __init__(self):
- # cached fields: {descr: CachedField}
- self.cached_fields = {}
+ # mapping descr -> infos to invalidate
+ self.infos_to_invalidate = {}
# cached array items: {array descr: {index: CachedField}}
self.cached_arrayitems = {}
# cached dict items: {dict descr: {(optval, index): box-or-const}}
@@ -203,15 +203,6 @@
def setup(self):
self.optimizer.optheap = self
- def value_updated(self, oldvalue, newvalue):
- # XXXX very unhappy about that
- for cf in self.cached_fields.itervalues():
- cf.value_updated(oldvalue, newvalue,
self.optimizer.exporting_state)
- for submap in self.cached_arrayitems.itervalues():
- for cf in submap.itervalues():
- cf.value_updated(oldvalue, newvalue,
- self.optimizer.exporting_state)
-
def force_at_end_of_preamble(self):
self.cached_dict_reads.clear()
self.corresponding_array_descrs.clear()
@@ -247,9 +238,22 @@
for index, d in submap.items():
d.produce_potential_short_preamble_ops(self.optimizer, sb,
descr)
+ def invalidate_descr(self, descr, lst=None):
+ if lst is not None:
+ lst = self.infos_to_invalidate.get(descr, None)
+ if lst is None:
+ return
+ for info in lst:
+ info.clear_cache()
+ del lst[:]
+
+ def register_dirty_field(self, descr, info):
+ self.infos_to_invalidate.setdefault(descr, []).append(info)
+
def clean_caches(self):
del self._lazy_setfields_and_arrayitems[:]
- self.cached_fields.clear()
+ for descr, info in self.infos_to_invalidate.iteritems():
+ self.invalidate_descr(descr, info)
self.cached_arrayitems.clear()
self.cached_dict_reads.clear()
@@ -478,7 +482,15 @@
return pendingfields
def optimize_GETFIELD_GC_I(self, op):
+ opinfo = self.ensure_ptr_info_arg0(op)
+ fld = opinfo.getfield(op.getdescr())
+ if fld is not None:
+ self.make_equal_to(op, fld)
+ return
self.emit_operation(op)
+ opinfo.setfield(op.getdescr(), op, self)
+ return
+ xxx
return
structvalue = self.getvalue(op.getarg(0))
cf = self.field_cache(op.getdescr())
@@ -522,6 +534,8 @@
cf.do_setfield(self, op)
def optimize_GETARRAYITEM_GC_I(self, op):
+ self.emit_operation(op)
+ return # XXX
arrayvalue = self.getvalue(op.getarg(0))
indexvalue = self.getvalue(op.getarg(1))
cf = None
@@ -569,6 +583,8 @@
optimize_GETARRAYITEM_GC_PURE_F = optimize_GETARRAYITEM_GC_PURE_I
def optimize_SETARRAYITEM_GC(self, op):
+ self.emit_operation(op)
+ return
opnum = OpHelpers.getarrayitem_pure_for_descr(op.getdescr())
if self.has_pure_result(opnum, [op.getarg(0), op.getarg(1)],
op.getdescr()):
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
@@ -8,19 +8,20 @@
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'
+MODE_INSTANCE = '\x03'
+MODE_STRUCT = '\x04'
INFO_NULL = 0
INFO_NONNULL = 1
INFO_UNKNOWN = 2
+FLAG_VIRTUAL = 1
+FLAG_DIRTY = 2
+
class AbstractInfo(AbstractValue):
is_info_class = True
@@ -55,39 +56,54 @@
return True
class AbstractVirtualPtrInfo(NonNullPtrInfo):
- _attrs_ = ('_is_virtual',)
+ _attrs_ = ('flags',)
+
+ flags = 0
def force_box(self, op, optforce):
- if self._is_virtual:
+ if self.is_virtual():
op.set_forwarded(None)
optforce.emit_operation(op)
newop = optforce.getlastop()
op.set_forwarded(newop)
newop.set_forwarded(self)
- self._is_virtual = False
- self._force_elements(newop, optforce)
+ self.flags &= ~FLAG_VIRTUAL # clean the virtual flag
+ if self._force_elements(newop, optforce):
+ self.flags |= FLAG_DIRTY
return newop
return op
def is_virtual(self):
- return self._is_virtual
+ return self.flags & FLAG_VIRTUAL
class AbstractStructPtrInfo(AbstractVirtualPtrInfo):
- _attrs_ = ('_is_virtual', '_fields')
+ _attrs_ = ('_fields',)
def init_fields(self, descr):
self._fields = [None] * len(descr.all_fielddescrs)
- def setfield_virtual(self, descr, op):
+ def clear_cache(self):
+ assert self.flags & (FLAG_DIRTY | FLAG_VIRTUAL) == FLAG_DIRTY
+ self.flags = 0
+ self._fields = [None] * len(self._fields)
+
+ def setfield(self, descr, op, optheap=None):
+ if not self.is_virtual():
+ if self.flags & FLAG_DIRTY == 0:
+ self.flags |= FLAG_DIRTY
+ assert optheap is not None
+ # we should only call it with virtuals without optheap
+ optheap.register_dirty_field(descr, self)
self._fields[descr.index] = op
- def getfield_virtual(self, descr):
+ def getfield(self, descr):
return self._fields[descr.index]
def _force_elements(self, op, optforce):
if self._fields is None:
- return
+ return 0
descr = op.getdescr()
+ count = 0
for i, flddescr in enumerate(descr.all_fielddescrs):
fld = self._fields[i]
if fld is not None:
@@ -95,6 +111,10 @@
setfieldop = ResOperation(rop.SETFIELD_GC, [op, subbox],
descr=flddescr)
optforce.emit_operation(setfieldop)
+ if optforce.optheap:
+ optforce.optheap.register_dirty_field(flddescr, self)
+ count += 1
+ return count
class InstancePtrInfo(AbstractStructPtrInfo):
_attrs_ = ('_known_class')
@@ -102,25 +122,44 @@
def __init__(self, known_class=None, is_virtual=False):
self._known_class = known_class
- self._is_virtual = is_virtual
+ if is_virtual:
+ self.flags = FLAG_VIRTUAL
def get_known_class(self, cpu):
return self._known_class
class StructPtrInfo(AbstractStructPtrInfo):
- pass
+ def __init__(self, is_virtual=False):
+ if is_virtual:
+ self.flags = FLAG_VIRTUAL
class ArrayPtrInfo(AbstractVirtualPtrInfo):
- _attrs_ = ('_is_virtual', 'length', '_items', '_descr')
+ _attrs_ = ('length', '_items', '_descr')
def __init__(self, descr, const, size, clear, is_virtual):
- self._is_virtual = is_virtual
+ if is_virtual:
+ self.flags = FLAG_VIRTUAL
self.length = size
if clear:
self._items = [const] * size
else:
self._items = [None] * size
+ def _force_elements(self, op, optforce):
+ arraydescr = op.getdescr()
+ count = 0
+ for i in range(self.length):
+ item = self._items[i]
+ if item is not None:
+ subbox = optforce.force_box(item)
+ setop = ResOperation(rop.SETARRAYITEM_GC,
+ [op, ConstInt(i), subbox],
+ descr=arraydescr)
+ optforce.emit_operation(setop)
+ # xxxx optforce.optheap
+ count += 1
+ return count
+
def setitem_virtual(self, index, item):
self._items[index] = item
@@ -134,7 +173,8 @@
def __init__(self, descr, size, is_virtual):
self.length = size
lgt = len(descr.all_interiorfielddescrs)
- self._is_virtual = is_virtual
+ if is_virtual:
+ self.flags = FLAG_VIRTUAL
self._items = [None] * (size * lgt)
def _compute_index(self, index, fielddescr):
@@ -152,6 +192,7 @@
def _force_elements(self, op, optforce):
i = 0
fielddescrs = op.getdescr().all_interiorfielddescrs
+ count = 0
for index in range(self.length):
for flddescr in fielddescrs:
fld = self._items[i]
@@ -161,7 +202,10 @@
[op, ConstInt(index), subbox],
descr=flddescr)
optforce.emit_operation(setfieldop)
+ # XXX optforce.optheap
+ count += 1
i += 1
+ return count
class StrPtrInfo(NonNullPtrInfo):
_attrs_ = ()
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
@@ -71,21 +71,21 @@
optimize_GUARD_VALUE = _optimize_guard_true_false_value
def optimize_INT_OR_or_XOR(self, op):
- v1 = self.getvalue(op.getarg(0))
- v2 = self.getvalue(op.getarg(1))
- if v1.box is v2.box:
+ v1 = self.get_box_replacement(op.getarg(0))
+ b1 = self.getintbound(v1)
+ v2 = self.get_box_replacement(op.getarg(1))
+ b2 = self.getintbound(v2)
+ if v1 is v2:
if op.getopnum() == rop.INT_OR:
self.make_equal_to(op, v1)
else:
self.make_constant_int(op, 0)
return
self.emit_operation(op)
- bound1 = v1.getintbound()
- bound2 = v2.getintbound()
- if bound1.known_ge(IntBound(0, 0)) and \
- bound2.known_ge(IntBound(0, 0)):
- r = self.getvalue(op).getintbound()
- mostsignificant = bound1.upper | bound2.upper
+ if b1.known_ge(IntBound(0, 0)) and \
+ b2.known_ge(IntBound(0, 0)):
+ r = self.getintbound(op)
+ mostsignificant = b1.upper | b2.upper
r.intersect(IntBound(0, next_pow2_m1(mostsignificant)))
optimize_INT_OR = optimize_INT_OR_or_XOR
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
@@ -304,7 +304,7 @@
op.set_forwarded(opinfo)
return opinfo
- def getptrinfo(self, op):
+ def getptrinfo(self, op, create=False, is_object=False):
assert op.type == 'r'
op = self.get_box_replacement(op)
assert op.type == 'r'
@@ -325,8 +325,8 @@
def replace_op_with(self, op, newopnum, args=None, descr=None):
return self.optimizer.replace_op_with(op, newopnum, args, descr)
- def get_box_replacement(self, box):
- return self.optimizer.get_box_replacement(box)
+ def ensure_ptr_info_arg0(self, op):
+ return self.optimizer.ensure_ptr_info_arg0(op)
def make_constant(self, box, constbox):
return self.optimizer.make_constant(box, constbox)
@@ -575,6 +575,35 @@
return
op.set_forwarded(info.NonNullPtrInfo())
+ def ensure_ptr_info_arg0(self, op):
+ arg0 = self.get_box_replacement(op.getarg(0))
+ if arg0.is_constant():
+ return info.ConstPtrInfo(arg0)
+ opinfo = arg0.get_forwarded()
+ if isinstance(opinfo, info.AbstractVirtualPtrInfo):
+ return opinfo
+ assert opinfo is None or opinfo.__class__ is info.NonNullPtrInfo
+ if op.is_getfield() or op.getopnum() == rop.SETFIELD_GC:
+ is_object = op.getdescr().parent_descr.is_object()
+ if is_object:
+ opinfo = info.InstancePtrInfo()
+ else:
+ xxx
+ opinfo.init_fields(op.getdescr().parent_descr)
+ else:
+ yyy
+ arg0.set_forwarded(opinfo)
+ return opinfo
+
+ def make_ptr_info(self, op, mode):
+ op = self.get_box_replacement(op)
+ if op.is_constant():
+ return info.ConstPtrInfo(op)
+ opinfo = op.get_forwarded()
+ if isinstance(opinfo, info.AbstractVirtualPtrInfo):
+ return opinfo
+ xxx
+
def new_const(self, fieldofs):
if fieldofs.is_pointer_field():
return self.cpu.ts.CONST_NULL
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), descr=nodesize)
+ p0 = new_with_vtable(descr=nodesize)
escape_n(p0)
guard_class(p0, ConstClass(node_vtable)) []
jump(i0)
"""
expected = """
[i0]
- p0 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
+ p0 = new_with_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), descr=nodesize)
+ pv = new_with_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), descr=nodesize)
+ p1 = new_with_vtable(descr=nodesize)
setfield_gc(p1, i1, descr=valuedescr)
jump(i1, p1, p2)
"""
@@ -587,9 +587,9 @@
[i1, p2, p3]
i3 = getfield_gc_i(p3, descr=valuedescr)
escape_n(i3)
- p1 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
+ p1 = new_with_vtable(descr=nodesize)
setfield_gc(p1, i1, descr=valuedescr)
- p1sub = new_with_vtable(ConstClass(node_vtable2), descr=nodesize2)
+ p1sub = new_with_vtable(descr=nodesize2)
setfield_gc(p1sub, i1, descr=valuedescr)
setfield_gc(p1, p1sub, descr=nextdescr)
jump(i1, p1, p2)
@@ -604,10 +604,10 @@
p3sub = getfield_gc_r(p3, descr=nextdescr)
i3 = getfield_gc_i(p3sub, descr=valuedescr)
escape_n(i3)
- p2sub = new_with_vtable(ConstClass(node_vtable2), descr=nodesize2)
+ p2sub = new_with_vtable(descr=nodesize2)
setfield_gc(p2sub, i1, descr=valuedescr)
setfield_gc(p2, p2sub, descr=nextdescr)
- p1 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
+ p1 = new_with_vtable(descr=nodesize)
jump(i1, p1, p2)
"""
# The same as test_p123_simple, but in the end the "old" p2 contains
@@ -736,6 +736,7 @@
expected)
def test_virtual_2(self):
+ py.test.skip("XXX")
ops = """
[i, p0]
i0 = getfield_gc(p0, descr=valuedescr)
@@ -749,7 +750,6 @@
i1 = int_add(i2, i)
jump(i, i1)
"""
- py.test.skip("XXX")
self.optimize_loop(ops, 'Not, Virtual(node_vtable, valuedescr=Not)',
expected)
@@ -807,6 +807,7 @@
self.optimize_loop(ops, expected2)
def test_virtual_default_field(self):
+ py.test.skip("XXX")
ops = """
[p0]
i0 = getfield_gc(p0, descr=valuedescr)
@@ -822,14 +823,13 @@
"""
# the 'expected' is sub-optimal, but it should be done by another later
# optimization step. See test_find_nodes_default_field() for why.
- py.test.skip("XXX")
self.optimize_loop(ops, 'Virtual(node_vtable, valuedescr=Not)',
expected)
def test_virtual_3(self):
ops = """
[i]
- p1 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
+ p1 = new_with_vtable(descr=nodesize)
setfield_gc(p1, i, descr=valuedescr)
i0 = getfield_gc_i(p1, descr=valuedescr)
i1 = int_add(i0, 1)
@@ -843,13 +843,14 @@
self.optimize_loop(ops, expected)
def test_virtual_4(self):
+ py.test.skip("XXX")
ops = """
[i0, p0]
guard_class(p0, ConstClass(node_vtable)) []
i1 = getfield_gc(p0, descr=valuedescr)
i2 = int_sub(i1, 1)
i3 = int_add(i0, i1)
- p1 = new_with_vtable(ConstClass(node_vtable))
+ p1 = new_with_vtable(descr=nodesize)
setfield_gc(p1, i2, descr=valuedescr)
jump(i3, p1)
"""
@@ -859,11 +860,11 @@
i3 = int_add(i0, i1)
jump(i3, i2)
"""
- py.test.skip("XXX")
self.optimize_loop(ops, 'Not, Virtual(node_vtable, valuedescr=Not)',
expected)
def test_virtual_5(self):
+ py.test.skip("XXX")
ops = """
[i0, p0]
guard_class(p0, ConstClass(node_vtable)) []
@@ -883,7 +884,6 @@
i3 = int_add(i0, i1)
jump(i3, i2, i1)
"""
- py.test.skip("XXX")
self.optimize_loop(ops,
'''Not, Virtual(node_vtable,
valuedescr=Not,
@@ -894,7 +894,7 @@
def test_virtual_constant_isnull(self):
ops = """
[i0]
- p0 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
+ p0 = new_with_vtable(descr=nodesize)
setfield_gc(p0, NULL, descr=nextdescr)
p2 = getfield_gc_r(p0, descr=nextdescr)
i1 = ptr_eq(p2, NULL)
@@ -909,7 +909,7 @@
def test_virtual_constant_isnonnull(self):
ops = """
[i0]
- p0 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
+ p0 = new_with_vtable(descr=nodesize)
setfield_gc(p0, ConstPtr(myptr), descr=nextdescr)
p2 = getfield_gc_r(p0, descr=nextdescr)
i1 = ptr_eq(p2, NULL)
@@ -1020,7 +1020,7 @@
def test_nonvirtual_1(self):
ops = """
[i]
- p1 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
+ p1 = new_with_vtable(descr=nodesize)
setfield_gc(p1, i, descr=valuedescr)
i0 = getfield_gc_i(p1, descr=valuedescr)
i1 = int_add(i0, 1)
@@ -1031,7 +1031,7 @@
expected = """
[i]
i1 = int_add(i, 1)
- p1 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
+ p1 = new_with_vtable(descr=nodesize)
setfield_gc(p1, i, descr=valuedescr)
escape_n(p1)
escape_n(p1)
@@ -1045,7 +1045,7 @@
i0 = getfield_gc_i(p0, descr=valuedescr)
escape_n(p0)
i1 = int_add(i0, i)
- p1 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
+ p1 = new_with_vtable(descr=nodesize)
setfield_gc(p1, i1, descr=valuedescr)
jump(i, p1)
"""
@@ -1055,7 +1055,7 @@
def test_nonvirtual_later(self):
ops = """
[i]
- p1 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
+ p1 = new_with_vtable(descr=nodesize)
setfield_gc(p1, i, descr=valuedescr)
i1 = getfield_gc_i(p1, descr=valuedescr)
escape_n(p1)
@@ -1065,7 +1065,7 @@
"""
expected = """
[i]
- p1 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
+ p1 = new_with_vtable(descr=nodesize)
setfield_gc(p1, i, descr=valuedescr)
escape_n(p1)
i2 = getfield_gc_i(p1, descr=valuedescr)
@@ -1077,7 +1077,7 @@
def test_nonvirtual_write_null_fields_on_force(self):
ops = """
[i]
- p1 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
+ p1 = new_with_vtable(descr=nodesize)
setfield_gc(p1, i, descr=valuedescr)
i1 = getfield_gc_i(p1, descr=valuedescr)
setfield_gc(p1, 0, descr=valuedescr)
@@ -1087,7 +1087,7 @@
"""
expected = """
[i]
- p1 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
+ p1 = new_with_vtable(descr=nodesize)
setfield_gc(p1, 0, descr=valuedescr)
escape_n(p1)
i2 = getfield_gc_i(p1, descr=valuedescr)
@@ -1098,7 +1098,7 @@
def test_getfield_gc_pure_1(self):
ops = """
[i]
- p1 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
+ p1 = new_with_vtable(descr=nodesize)
setfield_gc(p1, i, descr=valuedescr)
i1 = getfield_gc_pure_i(p1, descr=valuedescr)
jump(i1)
@@ -1189,8 +1189,8 @@
"""
expected = """
[i1, p0]
+ setarrayitem_gc(p0, 0, i1, descr=arraydescr)
p1 = new_array(i1, descr=arraydescr)
- setarrayitem_gc(p0, 0, i1, descr=arraydescr)
jump(i1, p1)
"""
self.optimize_loop(ops, expected)
@@ -1250,7 +1250,7 @@
def test_varray_forced_1(self):
ops = """
[]
- p2 = new_with_vtable(ConstClass(node_vtable))
+ p2 = new_with_vtable(descr=nodesize)
setfield_gc(p2, 3, descr=valuedescr)
i1 = getfield_gc_i(p2, descr=valuedescr) # i1 = const 3
p1 = new_array(i1, descr=arraydescr)
@@ -1270,6 +1270,7 @@
self.optimize_loop(ops, expected)
def test_vstruct_1(self):
+ py.test.skip("XXX")
ops = """
[i1, p2]
i2 = getfield_gc(p2, descr=adescr)
@@ -1283,7 +1284,6 @@
escape_n(i2)
jump(i1, i1)
"""
- py.test.skip("XXX")
self.optimize_loop(ops, 'Not, VStruct(ssize, adescr=Not)', expected)
def test_p123_vstruct(self):
@@ -1565,6 +1565,7 @@
self.optimize_loop(ops, expected)
def test_duplicate_setfield_5(self):
+ xxx
ops = """
[p0, i1]
p1 = new_with_vtable(ConstClass(node_vtable))
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_util.py
b/rpython/jit/metainterp/optimizeopt/test/test_util.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_util.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_util.py
@@ -109,8 +109,8 @@
myptr2 = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(NODE))
nullptr = lltype.nullptr(llmemory.GCREF.TO)
#nodebox2 = InputArgRef(lltype.cast_opaque_ptr(llmemory.GCREF, node2))
- nodesize = cpu.sizeof(NODE)
- nodesize2 = cpu.sizeof(NODE2)
+ nodesize = cpu.sizeof(NODE, True)
+ nodesize2 = cpu.sizeof(NODE2, True)
valuedescr = cpu.fielddescrof(NODE, 'value')
floatdescr = cpu.fielddescrof(NODE, 'floatval')
chardescr = cpu.fielddescrof(NODE, 'charval')
@@ -122,7 +122,7 @@
QUASI = lltype.GcStruct('QUASIIMMUT', ('inst_field', lltype.Signed),
('mutate_field', rclass.OBJECTPTR),
hints={'immutable_fields': accessor})
- quasisize = cpu.sizeof(QUASI)
+ quasisize = cpu.sizeof(QUASI, False)
quasi = lltype.malloc(QUASI, immortal=True)
quasi.inst_field = -4247
quasifielddescr = cpu.fielddescrof(QUASI, 'inst_field')
@@ -157,7 +157,7 @@
# a GcStruct not inheriting from OBJECT
S = lltype.GcStruct('TUPLE', ('a', lltype.Signed), ('b', lltype.Ptr(NODE)))
- ssize = cpu.sizeof(S)
+ ssize = cpu.sizeof(S, False)
adescr = cpu.fielddescrof(S, 'a')
bdescr = cpu.fielddescrof(S, 'b')
#sbox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(S)))
@@ -166,7 +166,7 @@
T = lltype.GcStruct('TUPLE',
('c', lltype.Signed),
('d', lltype.Ptr(lltype.GcArray(lltype.Ptr(NODE)))))
- tsize = cpu.sizeof(T)
+ tsize = cpu.sizeof(T, False)
cdescr = cpu.fielddescrof(T, 'c')
ddescr = cpu.fielddescrof(T, 'd')
arraydescr3 = cpu.arraydescrof(lltype.GcArray(lltype.Ptr(NODE)))
@@ -176,7 +176,7 @@
('one', lltype.Ptr(lltype.GcArray(lltype.Ptr(NODE)))))
u_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
u_vtable_adr = llmemory.cast_ptr_to_adr(u_vtable)
- usize = cpu.sizeof(U)
+ usize = cpu.sizeof(U, True)
onedescr = cpu.fielddescrof(U, 'one')
FUNC = lltype.FuncType([lltype.Signed], lltype.Signed)
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
@@ -1,6 +1,6 @@
from rpython.jit.codewriter.effectinfo import EffectInfo
from rpython.jit.metainterp.executor import execute
-from rpython.jit.codewriter.heaptracker import vtable2descr
+from rpython.jit.codewriter.heaptracker import vtable2descr, descr2vtable
from rpython.jit.metainterp.history import Const, ConstInt, BoxInt
from rpython.jit.metainterp.history import CONST_NULL, BoxPtr
from rpython.jit.metainterp.optimizeopt import info, optimizer
@@ -15,7 +15,6 @@
class AbstractVirtualInfo(info.PtrInfo):
_attrs_ = ('_cached_vinfo',)
- _tag = info.LEVEL_NONNULL
is_about_raw = False
_cached_vinfo = None
@@ -188,7 +187,6 @@
fieldvalue.visitor_walk_recursive(visitor)
class VirtualInfo(AbstractVirtualStructInfo):
- _tag = info.LEVEL_KNOWNCLASS
def __init__(self, known_class, descr):
AbstractVirtualStructInfo.__init__(self)
@@ -539,9 +537,10 @@
return opinfo
def make_vstruct(self, structdescr, source_op):
- vvalue = VStructValue(self.optimizer.cpu, structdescr, source_op)
- self.make_equal_to(source_op, vvalue)
- return vvalue
+ opinfo = info.StructPtrInfo(True)
+ opinfo.init_fields(structdescr)
+ source_op.set_forwarded(opinfo)
+ return opinfo
def make_virtual_raw_memory(self, size, source_op):
logops = self.optimizer.loop.logops
@@ -678,7 +677,7 @@
# self.make_equal_to(op, fieldvalue)
# return
if opinfo and opinfo.is_virtual():
- fieldop = opinfo.getfield_virtual(op.getdescr())
+ fieldop = opinfo.getfield(op.getdescr())
if fieldop is None:
xxx
fieldvalue = self.optimizer.new_const(op.getdescr())
@@ -698,14 +697,15 @@
def optimize_SETFIELD_GC(self, op):
opinfo = self.getptrinfo(op.getarg(0))
if opinfo is not None and opinfo.is_virtual():
- opinfo.setfield_virtual(op.getdescr(),
- self.get_box_replacement(op.getarg(1)))
+ opinfo.setfield(op.getdescr(),
+ self.get_box_replacement(op.getarg(1)))
else:
self.make_nonnull(op.getarg(0))
self.emit_operation(op)
def optimize_NEW_WITH_VTABLE(self, op):
- self.make_virtual(op.getarg(0), op, op.getdescr())
+ known_class = ConstInt(descr2vtable(self.optimizer.cpu, op.getdescr()))
+ self.make_virtual(known_class, 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,8 +3,6 @@
ConstPtr, ConstFloat)
from rpython.jit.metainterp.optimizeopt import virtualize
from rpython.jit.metainterp.optimizeopt.intutils import IntUnbounded
-from rpython.jit.metainterp.optimizeopt.info import (LEVEL_CONSTANT,
- LEVEL_KNOWNCLASS, LEVEL_NONNULL, LEVEL_UNKNOWN)
from rpython.jit.metainterp.resoperation import rop, ResOperation,\
AbstractInputArg
from rpython.jit.metainterp.compile import Memo
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
@@ -223,6 +223,10 @@
def is_call(self):
return rop._CALL_FIRST <= self.getopnum() <= rop._CALL_LAST
+ def is_getfield(self):
+ return self.opnum in (rop.GETFIELD_GC_I, rop.GETFIELD_GC_F,
+ rop.GETFIELD_GC_R)
+
def is_real_call(self):
opnum = self.opnum
return (opnum == rop.CALL_I or
@@ -719,7 +723,7 @@
'GETFIELD_RAW/1d/fi',
'_MALLOC_FIRST',
'NEW/0d/r', #-> GcStruct, gcptrs inside are zeroed (not the rest)
- 'NEW_WITH_VTABLE/1d/r',#-> GcStruct with vtable, gcptrs inside are zeroed
+ 'NEW_WITH_VTABLE/0d/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
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit