Author: Maciej Fijalkowski <fij...@gmail.com> Branch: optresult-unroll Changeset: r79421:a2668c2f5ddf Date: 2015-09-04 15:22 +0200 http://bitbucket.org/pypy/pypy/changeset/a2668c2f5ddf/
Log: merge diff --git a/rpython/jit/backend/llsupport/gc.py b/rpython/jit/backend/llsupport/gc.py --- a/rpython/jit/backend/llsupport/gc.py +++ b/rpython/jit/backend/llsupport/gc.py @@ -693,6 +693,17 @@ expected_typeid >>= 2 return expected_typeid + def get_translated_info_for_typeinfo(self): + from rpython.memory.gctypelayout import GCData + type_info_group = llop.gc_get_type_info_group(llmemory.Address) + type_info_group = rffi.cast(lltype.Signed, type_info_group) + if WORD == 4: + shift_by = 2 + elif WORD == 8: + shift_by = 0 + sizeof_ti = rffi.sizeof(GCData.TYPE_INFO) + return (type_info_group, shift_by, sizeof_ti) + def _setup_guard_is_object(self): from rpython.memory.gctypelayout import GCData, T_IS_RPYTHON_INSTANCE self._infobits_offset, _ = symbolic.get_field_token(GCData.TYPE_INFO, @@ -700,16 +711,8 @@ self._T_IS_RPYTHON_INSTANCE = T_IS_RPYTHON_INSTANCE def get_translated_info_for_guard_is_object(self): - type_info_group = llop.gc_get_type_info_group(llmemory.Address) - type_info_group = rffi.cast(lltype.Signed, type_info_group) infobits_offset = rffi.cast(lltype.Signed, self._infobits_offset) - if WORD == 4: - shift_by = 2 - elif WORD == 8: - shift_by = 0 - return (type_info_group + infobits_offset, - shift_by, - self._T_IS_RPYTHON_INSTANCE) + return (infobits_offset, self._T_IS_RPYTHON_INSTANCE) # ____________________________________________________________ diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -54,6 +54,8 @@ self.vtable_offset, _ = symbolic.get_field_token(rclass.OBJECT, 'typeptr', translate_support_code) + self.subclassrange_min_offset, _ = symbolic.get_field_token( + rclass.OBJECT_VTABLE, 'subclassrange_min', translate_support_code) if translate_support_code: self._setup_exception_handling_translated() else: diff --git a/rpython/jit/backend/llsupport/test/test_zrpy_gc_direct.py b/rpython/jit/backend/llsupport/test/test_zrpy_gc_direct.py --- a/rpython/jit/backend/llsupport/test/test_zrpy_gc_direct.py +++ b/rpython/jit/backend/llsupport/test/test_zrpy_gc_direct.py @@ -72,14 +72,24 @@ """, namespace={'finaldescr': finaldescr, 'faildescr': faildescr}) + loop4 = parse(""" + [p0] + guard_subclass(p0, ConstInt(vtable_B), descr=faildescr) [] + finish(descr=finaldescr) + """, namespace={'finaldescr': finaldescr, + 'faildescr': faildescr, + 'vtable_B': vtable_B}) + def g(): cpu.setup_once() token1 = JitCellToken() token2 = JitCellToken() token3 = JitCellToken() + token4 = JitCellToken() cpu.compile_loop(loop1.inputargs, loop1.operations, token1) cpu.compile_loop(loop2.inputargs, loop2.operations, token2) cpu.compile_loop(loop3.inputargs, loop3.operations, token3) + cpu.compile_loop(loop4.inputargs, loop4.operations, token4) for token, p0 in [ (token1, rffi.cast(llmemory.GCREF, A())), @@ -94,6 +104,10 @@ (token3, rffi.cast(llmemory.GCREF, A())), (token3, rffi.cast(llmemory.GCREF, B())), (token3, rffi.cast(llmemory.GCREF, [44, 45])), + + (token4, rffi.cast(llmemory.GCREF, A())), + (token4, rffi.cast(llmemory.GCREF, B())), + (token4, rffi.cast(llmemory.GCREF, C())), ]: frame = execute_token(token, p0) descr = cpu.get_latest_descr(frame) @@ -122,7 +136,11 @@ 'match\n' 'match\n' - 'fail\n') + 'fail\n' + + 'fail\n' + 'match\n' + 'match\n') def test_guards_translated_with_gctypeptr(): diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -11,6 +11,7 @@ from rpython.rtyper.lltypesystem import lltype, rffi, rstr, llmemory from rpython.rtyper.lltypesystem.lloperation import llop from rpython.rtyper.annlowlevel import llhelper, cast_instance_to_gcref +from rpython.rtyper import rclass from rpython.rlib.jit import AsmInfo from rpython.jit.backend.model import CompiledLoopToken from rpython.jit.backend.x86.regalloc import (RegAlloc, get_ebp_ofs, @@ -1786,17 +1787,58 @@ [loc_object, loc_typeid] = locs # idea: read the typeid, fetch the field 'infobits' from the big # typeinfo table, and check the flag 'T_IS_RPYTHON_INSTANCE'. - base_type_info, shift_by, IS_OBJECT_FLAG = ( - self.cpu.gc_ll_descr.get_translated_info_for_guard_is_object()) if IS_X86_32: self.mc.MOVZX16(loc_typeid, mem(loc_object, 0)) else: self.mc.MOV32(loc_typeid, mem(loc_object, 0)) - loc_infobits = addr_add(imm(base_type_info), loc_typeid, scale=shift_by) + # + base_type_info, shift_by, sizeof_ti = ( + self.cpu.gc_ll_descr.get_translated_info_for_typeinfo()) + infobits_offset, IS_OBJECT_FLAG = ( + self.cpu.gc_ll_descr.get_translated_info_for_guard_is_object()) + loc_infobits = addr_add(imm(base_type_info), loc_typeid, + scale=shift_by, offset=infobits_offset) self.mc.TEST(loc_infobits, imm(IS_OBJECT_FLAG)) # self.implement_guard(guard_token, 'Z') + def genop_guard_guard_subclass(self, op, guard_op, + guard_token, locs, ign_2): + assert self.cpu.supports_guard_gc_type + [loc_object, loc_check_against_class, loc_tmp] = locs + assert isinstance(loc_object, RegLoc) + assert isinstance(loc_tmp, RegLoc) + offset = self.cpu.vtable_offset + offset2 = self.cpu.subclassrange_min_offset + if offset is not None: + # read this field to get the vtable pointer + self.mc.MOV_rm(loc_tmp.value, (loc_object.value, offset)) + # read the vtable's subclassrange_min field + self.mc.MOV_rm(loc_tmp.value, (loc_tmp.value, offset2)) + else: + # read the typeid + if IS_X86_32: + self.mc.MOVZX16(loc_tmp, mem(loc_object, 0)) + else: + self.mc.MOV32(loc_tmp, mem(loc_object, 0)) + # read the vtable's subclassrange_min field, as a single + # step with the correct offset + base_type_info, shift_by, sizeof_ti = ( + self.cpu.gc_ll_descr.get_translated_info_for_typeinfo()) + self.mc.MOV(loc_tmp, addr_add(imm(base_type_info), loc_tmp, + scale = shift_by, + offset = sizeof_ti + offset2)) + # get the two bounds to check against + vtable_ptr = loc_check_against_class.getint() + vtable_ptr = rffi.cast(rclass.CLASSTYPE, vtable_ptr) + check_min = vtable_ptr.subclassrange_min + check_max = vtable_ptr.subclassrange_max + # check by doing the unsigned comparison (tmp - min) < (max - min) + self.mc.SUB_ri(loc_tmp.value, check_min) + self.mc.CMP_ri(loc_tmp.value, check_max - check_min) + # the guard fails if we get a "not below" result + self.implement_guard(guard_token, 'NB') + def implement_guard_recovery(self, guard_opnum, faildescr, failargs, fail_locs, frame_depth): exc = (guard_opnum == rop.GUARD_EXCEPTION or diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py --- a/rpython/jit/backend/x86/regalloc.py +++ b/rpython/jit/backend/x86/regalloc.py @@ -438,7 +438,12 @@ self.perform_guard(op, [x, y], None) def consider_guard_subclass(self, op): - assert 0 # xxx + x = self.make_sure_var_in_reg(op.getarg(0)) + y = self.loc(op.getarg(1)) + tmp_box = TempVar() + z = self.rm.force_allocate_reg(tmp_box) + self.rm.possibly_free_var(tmp_box) + self.perform_guard(op, [x, y, z], None) def _consider_binop_part(self, op, symm=False): x = op.getarg(0) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit