Author: Armin Rigo <ar...@tunes.org> Branch: py3k Changeset: r87085:a65846c5dec3 Date: 2016-09-13 19:06 +0200 http://bitbucket.org/pypy/pypy/changeset/a65846c5dec3/
Log: hg merge default 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 @@ -3,7 +3,7 @@ from rpython.jit.metainterp.resoperation import AbstractValue, ResOperation,\ rop, OpHelpers from rpython.jit.metainterp.history import ConstInt, Const -from rpython.rtyper.lltypesystem import lltype +from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.jit.metainterp.optimizeopt.rawbuffer import RawBuffer, InvalidRawOperation from rpython.jit.metainterp.executor import execute from rpython.jit.metainterp.optimize import InvalidLoop 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 @@ -11,6 +11,8 @@ from rpython.jit.metainterp.typesystem import llhelper from rpython.rlib.objectmodel import specialize, we_are_translated from rpython.rlib.debug import debug_print +from rpython.rtyper import rclass +from rpython.rtyper.lltypesystem import llmemory from rpython.jit.metainterp.optimize import SpeculativeError @@ -799,6 +801,21 @@ if not (0 <= index < arraylength): raise SpeculativeError + @staticmethod + def _check_subclass(vtable1, vtable2): # checks that vtable1 is a subclass of vtable2 + known_class = llmemory.cast_adr_to_ptr( + llmemory.cast_int_to_adr(vtable1), + rclass.CLASSTYPE) + expected_class = llmemory.cast_adr_to_ptr( + llmemory.cast_int_to_adr(vtable2), + rclass.CLASSTYPE) + # note: the test is for a range including 'max', but 'max' + # should never be used for actual classes. Including it makes + # it easier to pass artificial tests. + return (expected_class.subclassrange_min + <= known_class.subclassrange_min + <= expected_class.subclassrange_max) + def is_virtual(self, op): if op.type == 'r': opinfo = self.getptrinfo(op) 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 @@ -324,37 +324,24 @@ return self.emit_operation(op) - def _check_subclass(self, vtable1, vtable2): - # checks that vtable1 is a subclass of vtable2 - known_class = llmemory.cast_adr_to_ptr( - llmemory.cast_int_to_adr(vtable1), - rclass.CLASSTYPE) - expected_class = llmemory.cast_adr_to_ptr( - llmemory.cast_int_to_adr(vtable2), - rclass.CLASSTYPE) - if (expected_class.subclassrange_min - <= known_class.subclassrange_min - <= expected_class.subclassrange_max): - return True - return False - def optimize_GUARD_SUBCLASS(self, op): info = self.getptrinfo(op.getarg(0)) + optimizer = self.optimizer if info and info.is_constant(): c = self.get_box_replacement(op.getarg(0)) - vtable = self.optimizer.cpu.ts.cls_of_box(c).getint() - if self._check_subclass(vtable, op.getarg(1).getint()): + vtable = optimizer.cpu.ts.cls_of_box(c).getint() + if optimizer._check_subclass(vtable, op.getarg(1).getint()): return raise InvalidLoop("GUARD_SUBCLASS(const) proven to always fail") if info is not None and info.is_about_object(): - known_class = info.get_known_class(self.optimizer.cpu) + known_class = info.get_known_class(optimizer.cpu) if known_class: - if self._check_subclass(known_class.getint(), - op.getarg(1).getint()): + if optimizer._check_subclass(known_class.getint(), + op.getarg(1).getint()): return elif info.get_descr() is not None: - if self._check_subclass(info.get_descr().get_vtable(), - op.getarg(1).getint()): + if optimizer._check_subclass(info.get_descr().get_vtable(), + op.getarg(1).getint()): return self.emit_operation(op) diff --git a/rpython/jit/metainterp/optimizeopt/test/test_unroll.py b/rpython/jit/metainterp/optimizeopt/test/test_unroll.py --- a/rpython/jit/metainterp/optimizeopt/test/test_unroll.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_unroll.py @@ -17,12 +17,13 @@ from rpython.jit.metainterp.optimizeopt.virtualstate import \ NotVirtualStateInfo, LEVEL_CONSTANT, LEVEL_UNKNOWN, LEVEL_KNOWNCLASS,\ VirtualStateInfo -from rpython.jit.metainterp.optimizeopt import info +from rpython.jit.metainterp.optimizeopt import info, optimizer from rpython.jit.codewriter import heaptracker from rpython.jit.tool import oparser class FakeOptimizer(object): optearlyforce = None + optimizer = optimizer.Optimizer class cpu: remove_gctypeptr = True 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 @@ -102,6 +102,8 @@ node_vtable_adr2 = llmemory.cast_ptr_to_adr(node_vtable2) node_vtable3 = lltype.malloc(OBJECT_VTABLE, immortal=True) node_vtable3.name = rclass.alloc_array_name('node3') + node_vtable3.subclassrange_min = 3 + node_vtable3.subclassrange_max = 3 node_vtable_adr3 = llmemory.cast_ptr_to_adr(node_vtable3) cpu = runner.LLGraphCPU(None) diff --git a/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py b/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py --- a/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py @@ -3,7 +3,8 @@ from rpython.jit.metainterp.optimizeopt.virtualstate import VirtualStateInfo,\ VStructStateInfo, LEVEL_CONSTANT,\ VArrayStateInfo, not_virtual, VirtualState,\ - GenerateGuardState, VirtualStatesCantMatch, VArrayStructStateInfo + GenerateGuardState, VirtualStatesCantMatch, VArrayStructStateInfo,\ + VirtualStateConstructor from rpython.jit.metainterp.history import ConstInt, ConstPtr, TargetToken from rpython.jit.metainterp.resoperation import InputArgInt, InputArgRef,\ InputArgFloat @@ -26,6 +27,7 @@ def __init__(self, cpu): self.cpu = cpu self.optearlyforce = None + self.optimizer = Optimizer class BaseTestGenerateGuards(BaseTest): def setup_class(self): @@ -87,6 +89,33 @@ vs = VirtualState([info0]) assert vs.make_inputargs(args, optimizer) == [] + def test_make_inputargs_2(self): + # Ensure that make_inputargs properly errors with VirtualStatesCantMatch + # when the type information for a virtual field conflicts. In practice the + # expected and given field always share a common subclass. + # This check is needed as not all paths to make_inputargs in unroll.py + # are guarded by a call to generate_guards. + optimizer = FakeOptimizer(self.cpu) + classbox1 = self.cpu.ts.cls_of_box(InputArgRef(self.nodeaddr)) + innervalue1 = info.InstancePtrInfo(known_class=classbox1, is_virtual=True, descr=self.valuedescr.get_parent_descr()) + for field in self.valuedescr.get_parent_descr().get_all_fielddescrs(): + innervalue1.setfield(field, None, ConstInt(42)) + classbox2 = self.cpu.ts.cls_of_box(InputArgRef(self.myptr3)) + innervalue2 = info.InstancePtrInfo(known_class=classbox2, is_virtual=True, descr=self.valuedescr3.get_parent_descr()) + for field in self.valuedescr3.get_parent_descr().get_all_fielddescrs(): + innervalue2.setfield(field, None, ConstInt(42)) + + nodebox1 = InputArgRef(self.nodeaddr) + nodebox2 = InputArgRef(self.myptr3) + nodebox1.set_forwarded(innervalue1) + nodebox2.set_forwarded(innervalue2) + + constr = VirtualStateConstructor(optimizer) + vs = constr.get_virtual_state([nodebox1]) + + with py.test.raises(VirtualStatesCantMatch): + args = vs.make_inputargs([nodebox2], optimizer, force_boxes=True) + def test_position_generalization(self): def postest(info1, info2): info1.position = 0 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 @@ -177,6 +177,14 @@ def _generalization_of_structpart(self, other): raise NotImplementedError + @staticmethod + def descr_issubclass(descr1, descr2, optimizer): + if not descr1.is_object() or not descr2.is_object(): + return True + vtable1 = descr1.get_vtable() + vtable2 = descr2.get_vtable() + return optimizer._check_subclass(vtable1, vtable2) + def enum_forced_boxes(self, boxes, box, optimizer, force_boxes=False): box = optimizer.get_box_replacement(box) info = optimizer.getptrinfo(box) @@ -184,10 +192,14 @@ raise VirtualStatesCantMatch() else: assert isinstance(info, AbstractStructPtrInfo) + for i in range(len(self.fielddescrs)): state = self.fieldstate[i] + descr = self.fielddescrs[i].get_parent_descr() if not state: continue + if not self.descr_issubclass(info.descr, descr, optimizer.optimizer): + raise VirtualStatesCantMatch() if state.position > self.position: fieldbox = info._fields[i] state.enum_forced_boxes(boxes, fieldbox, optimizer, force_boxes) diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py --- a/rpython/rlib/rposix.py +++ b/rpython/rlib/rposix.py @@ -461,6 +461,8 @@ save_err=rffi.RFFI_SAVE_ERRNO) c_fdatasync = external('fdatasync', [rffi.INT], rffi.INT, save_err=rffi.RFFI_SAVE_ERRNO) +if not _WIN32: + c_sync = external('sync', [], lltype.Void) @replace_os_function('ftruncate') def ftruncate(fd, length): @@ -477,6 +479,9 @@ validate_fd(fd) handle_posix_error('fdatasync', c_fdatasync(fd)) +def sync(): + c_sync() + #___________________________________________________________________ c_chdir = external('chdir', [rffi.CCHARP], rffi.INT, diff --git a/rpython/rlib/test/test_rposix.py b/rpython/rlib/test/test_rposix.py --- a/rpython/rlib/test/test_rposix.py +++ b/rpython/rlib/test/test_rposix.py @@ -604,3 +604,7 @@ assert rposix.get_inheritable(fd1) == False os.close(fd1) os.close(fd2) + +def test_sync(): + if sys.platform != 'win32': + rposix.sync() _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit