[pypy-commit] pypy py3.6: Optimise the common case for str to int conversion
Author: Ronan Lamy Branch: py3.6 Changeset: r96815:102276149584 Date: 2019-06-17 20:03 +0100 http://bitbucket.org/pypy/pypy/changeset/102276149584/ Log:Optimise the common case for str to int conversion diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py --- a/pypy/objspace/std/unicodeobject.py +++ b/pypy/objspace/std/unicodeobject.py @@ -1882,6 +1882,14 @@ def unicode_to_decimal_w(space, w_unistr, allow_surrogates=False): if not isinstance(w_unistr, W_UnicodeObject): raise oefmt(space.w_TypeError, "expected unicode, got '%T'", w_unistr) +if w_unistr.is_ascii(): +# fast path +return w_unistr._utf8 +else: +return _unicode_to_decimal_w(space, w_unistr) + +def _unicode_to_decimal_w(space, w_unistr): +# slow path, in a separate function for the JIT's benefit utf8 = w_unistr._utf8 result = StringBuilder(w_unistr._len()) it = rutf8.Utf8StringIterator(utf8) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Cleanup unicode_to_decimal_w() to make it more similar to pypy3
Author: Ronan Lamy Branch: Changeset: r96814:cde3d214c398 Date: 2019-06-17 18:26 +0100 http://bitbucket.org/pypy/pypy/changeset/cde3d214c398/ Log:Cleanup unicode_to_decimal_w() to make it more similar to pypy3 diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py --- a/pypy/objspace/std/unicodeobject.py +++ b/pypy/objspace/std/unicodeobject.py @@ -49,7 +49,6 @@ # special-case in Python 2, which is exactly what we want here assert length == len(utf8str.decode('utf-8')) - @staticmethod def from_utf8builder(builder): return W_UnicodeObject( @@ -1097,11 +1096,11 @@ if rutf8.has_surrogates(utf8): utf8 = rutf8.reencode_utf8_with_surrogates(utf8) return space.newbytes(utf8) -return encode(space, w_obj, encoding, errors) +return encode(space, w_obj, encoding, errors) def decode_object(space, w_obj, encoding, errors): -from pypy.module._codecs.interp_codecs import lookup_codec, decode +from pypy.module._codecs.interp_codecs import lookup_codec, decode if errors is None or errors == 'strict': # fast paths if encoding is None: @@ -,7 +1110,7 @@ unicodehelper.check_ascii_or_raise(space, s) return space.newutf8(s, len(s)) if encoding == 'utf-8' or encoding == 'utf8': -if (space.isinstance_w(w_obj, space.w_unicode) or +if (space.isinstance_w(w_obj, space.w_unicode) or space.isinstance_w(w_obj, space.w_bytes)): s = space.utf8_w(w_obj) else: @@ -1720,34 +1719,28 @@ def unicode_to_decimal_w(space, w_unistr): if not isinstance(w_unistr, W_UnicodeObject): raise oefmt(space.w_TypeError, "expected unicode, got '%T'", w_unistr) -unistr = w_unistr._utf8 -result = ['\0'] * w_unistr._length -digits = ['0', '1', '2', '3', '4', - '5', '6', '7', '8', '9'] -res_pos = 0 -iter = rutf8.Utf8StringIterator(unistr) -for uchr in iter: +utf8 = w_unistr._utf8 +result = StringBuilder(w_unistr._len()) +it = rutf8.Utf8StringIterator(utf8) +for uchr in it: if W_UnicodeObject._isspace(uchr): -result[res_pos] = ' ' -res_pos += 1 +result.append(' ') continue -try: -result[res_pos] = digits[unicodedb.decimal(uchr)] -except KeyError: -if 0 < uchr < 256: -result[res_pos] = chr(uchr) -else: +if not (0 < uchr < 256): +try: +uchr = ord('0') + unicodedb.decimal(uchr) +except KeyError: w_encoding = space.newtext('decimal') -pos = iter.get_pos() +pos = it.get_pos() w_start = space.newint(pos) -w_end = space.newint(pos+1) +w_end = space.newint(pos + 1) w_reason = space.newtext('invalid decimal Unicode string') raise OperationError(space.w_UnicodeEncodeError, - space.newtuple([w_encoding, w_unistr, - w_start, w_end, - w_reason])) -res_pos += 1 -return ''.join(result) +space.newtuple([w_encoding, w_unistr, +w_start, w_end, +w_reason])) +result.append(chr(uchr)) +return result.build() _repr_function = rutf8.make_utf8_escape_function( ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy arm64: work more on write barrier
Author: Maciej Fijalkowski Branch: arm64 Changeset: r96812:7a1bbf798839 Date: 2019-06-17 14:08 + http://bitbucket.org/pypy/pypy/changeset/7a1bbf798839/ Log:work more on write barrier diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py --- a/rpython/jit/backend/aarch64/assembler.py +++ b/rpython/jit/backend/aarch64/assembler.py @@ -374,10 +374,9 @@ # A final TEST8 before the RET, for the caller. Careful to # not follow this instruction with another one that changes # the status of the CPU flags! -YYY -mc.LDRB_ri(r.ip.value, r.r0.value, -imm=descr.jit_wb_if_flag_byteofs) -mc.TST_ri(r.ip.value, imm=0x80) +mc.LDRB_ri(r.ip0.value, r.x0.value, descr.jit_wb_if_flag_byteofs) +mc.MOVZ_r_u16(r.ip1.value, 0x80, 0) +mc.TST_rr_shift(r.ip0.value, r.ip1.value, 0) # mc.LDR_ri(r.ip0.value, r.sp.value, WORD) mc.LDR_ri(r.ip1.value, r.sp.value, 0) diff --git a/rpython/jit/backend/aarch64/codebuilder.py b/rpython/jit/backend/aarch64/codebuilder.py --- a/rpython/jit/backend/aarch64/codebuilder.py +++ b/rpython/jit/backend/aarch64/codebuilder.py @@ -180,6 +180,11 @@ base = 0b1000101 self.write32((base << 21) | (rm << 16) | (rn << 5) | rd) +def AND_rr_shift(self, rd, rn, rm, shift, shifttype=0): +base = 0b10001010 +assert 0 <= shift < 64 +self.write32((base << 24) | (shifttype << 22) | (rm << 16) | (shift << 10) | (rn << 5) | rd) + def AND_ri(self, rd, rn, immed): assert immed == 0xFF # just one value for now, don't feel like # understanding IMMR/IMMS quite yet @@ -225,10 +230,16 @@ base = 0b1100101 self.write32((base << 21) | (rm << 16) | (rn << 5) | rd) -def MVN_rr(self, rd, rm): +def MVN_rr(self, rd, rm): # defaults to xzr base = 0b10101010001 self.write32((base << 21) | (rm << 16) | (0b1 << 5)| rd) +def MVN_rr_shift(self, rd, rm, shift=0, shifttype=0): # defaults to LSL +base = 0b10101010 +assert 0 <= shift < 64 +self.write32((base << 24) | (shifttype << 22) | (1 << 21) | + (rm << 16) | (shift << 10) | (0b1 << 5) | rd) + def SMULL_rr(self, rd, rn, rm): base = 0b10011011001 self.write32((base << 21) | (rm << 16) | (0b1 << 10) | (rn << 5) | rd) diff --git a/rpython/jit/backend/aarch64/opassembler.py b/rpython/jit/backend/aarch64/opassembler.py --- a/rpython/jit/backend/aarch64/opassembler.py +++ b/rpython/jit/backend/aarch64/opassembler.py @@ -5,7 +5,7 @@ from rpython.jit.backend.aarch64 import registers as r from rpython.jit.backend.aarch64.codebuilder import OverwritingBuilder from rpython.jit.backend.aarch64.callbuilder import Aarch64CallBuilder -from rpython.jit.backend.arm import conditions as c +from rpython.jit.backend.arm import conditions as c, shift from rpython.jit.backend.aarch64.arch import JITFRAME_FIXED_SIZE, WORD from rpython.jit.backend.aarch64.locations import imm from rpython.jit.backend.llsupport.assembler import GuardToken, BaseAssembler @@ -498,6 +498,10 @@ def emit_op_cond_call_gc_wb(self, op, arglocs): self._write_barrier_fastpath(self.mc, op.getdescr(), arglocs) +def emit_op_cond_call_gc_wb_array(self, op, arglocs): +self._write_barrier_fastpath(self.mc, op.getdescr(), arglocs, + array=True) + def _write_barrier_fastpath(self, mc, descr, arglocs, array=False, is_frame=False): # Write code equivalent to write_barrier() in the GC: it checks # a flag in the object at arglocs[0], and if set, it calls a @@ -530,12 +534,12 @@ # for cond_call_gc_wb_array, also add another fast path: # if GCFLAG_CARDS_SET, then we can just set one bit and be done if card_marking: -XXX +mc.MOVZ_r_u16(r.ip1.value, 0x80, 0) # GCFLAG_CARDS_SET is in this byte at 0x80 -mc.TST_ri(r.ip.value, imm=0x80) +mc.TST_rr_shift(r.ip0.value, r.ip1.value, 0) js_location = mc.currpos() -mc.BKPT() +mc.BRK() else: js_location = 0 @@ -573,45 +577,40 @@ # here, we can simply write again a conditional jump, which will be # taken if GCFLAG_CARDS_SET is still not set. jns_location = mc.currpos() -mc.BKPT() +mc.BRK() # # patch the JS above -offset = mc.currpos() +offset = mc.currpos() - js_location pmc = OverwritingBuilder(mc, js_location, WORD) -pmc.B_offs(offset, c.NE) # We want to jump if the z flag isn't set +pmc.B_ofs_cond(offset, c.NE) # We want to jump if the z flag isn't set # # case
[pypy-commit] pypy arm64: start fighting with write barriers
Author: Maciej Fijalkowski Branch: arm64 Changeset: r96811:09bce457dc4b Date: 2019-06-17 13:11 + http://bitbucket.org/pypy/pypy/changeset/09bce457dc4b/ Log:start fighting with write barriers diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py --- a/rpython/jit/backend/aarch64/assembler.py +++ b/rpython/jit/backend/aarch64/assembler.py @@ -30,6 +30,7 @@ def __init__(self, cpu, translate_support_code=False): ResOpAssembler.__init__(self, cpu, translate_support_code) self.failure_recovery_code = [0, 0, 0, 0] +self.wb_slowpath = [0, 0, 0, 0, 0] def assemble_loop(self, jd_id, unique_id, logger, loopname, inputargs, operations, looptoken, log): @@ -318,7 +319,76 @@ self.mc.B(self.propagate_exception_path) def _build_wb_slowpath(self, withcards, withfloats=False, for_frame=False): -pass # XXX +descr = self.cpu.gc_ll_descr.write_barrier_descr +if descr is None: +return +if not withcards: +func = descr.get_write_barrier_fn(self.cpu) +else: +if descr.jit_wb_cards_set == 0: +return +func = descr.get_write_barrier_from_array_fn(self.cpu) +if func == 0: +return +# +# This builds a helper function called from the slow path of +# write barriers. It must save all registers, and optionally +# all vfp registers. It takes a single argument which is in x0. +# It must keep stack alignment accordingly. +mc = InstrBuilder() +# +exc0 = exc1 = None +mc.SUB_ri(r.sp.value, r.sp.value, 2 * WORD) +mc.STR_ri(r.ip0.value, r.sp.value, WORD) +mc.STR_ri(r.lr.value, r.sp.value, 0) +if not for_frame: +self._push_all_regs_to_jitframe(mc, [], withfloats, callee_only=True) +else: +# NOTE: don't save registers on the jitframe here! It might +# override already-saved values that will be restored +# later... +# +# we're possibly called from the slowpath of malloc +# save the caller saved registers +# assuming we do not collect here +exc0, exc1 = r.r4, r.r5 +XXX +mc.PUSH([gpr.value for gpr in r.caller_resp] + [exc0.value, exc1.value]) +mc.VPUSH([vfpr.value for vfpr in r.caller_vfp_resp]) + +self._store_and_reset_exception(mc, exc0, exc1) +mc.BL(func) +# +if not for_frame: +self._pop_all_regs_from_jitframe(mc, [], withfloats, callee_only=True) +else: +XXX +self._restore_exception(mc, exc0, exc1) +mc.VPOP([vfpr.value for vfpr in r.caller_vfp_resp]) +assert exc0 is not None +assert exc1 is not None +mc.POP([gpr.value for gpr in r.caller_resp] + +[exc0.value, exc1.value]) +# +if withcards: +# A final TEST8 before the RET, for the caller. Careful to +# not follow this instruction with another one that changes +# the status of the CPU flags! +YYY +mc.LDRB_ri(r.ip.value, r.r0.value, +imm=descr.jit_wb_if_flag_byteofs) +mc.TST_ri(r.ip.value, imm=0x80) +# +mc.LDR_ri(r.ip0.value, r.sp.value, WORD) +mc.LDR_ri(r.ip1.value, r.sp.value, 0) +mc.ADD_ri(r.sp.value, r.sp.value, 2 * WORD) +mc.RET_r(r.ip1.value) +# +rawstart = mc.materialize(self.cpu, []) +if for_frame: +self.wb_slowpath[4] = rawstart +else: +self.wb_slowpath[withcards + 2 * withfloats] = rawstart def build_frame_realloc_slowpath(self): # this code should do the following steps diff --git a/rpython/jit/backend/aarch64/codebuilder.py b/rpython/jit/backend/aarch64/codebuilder.py --- a/rpython/jit/backend/aarch64/codebuilder.py +++ b/rpython/jit/backend/aarch64/codebuilder.py @@ -256,6 +256,11 @@ self.write32((base << 21) | (0b1 << 16) | (cond << 12) | (1 << 10) | (0b1 << 5) | rd) +def TST_rr_shift(self, rn, rm, shift): +assert 0 <= shift <= 64 +base = 0b1110101 +self.write32((base << 21) | (rm << 16) | (shift << 10) | (rn << 5) | 0b1) + def NOP(self): self.write32(0b1101010100110011) diff --git a/rpython/jit/backend/aarch64/opassembler.py b/rpython/jit/backend/aarch64/opassembler.py --- a/rpython/jit/backend/aarch64/opassembler.py +++ b/rpython/jit/backend/aarch64/opassembler.py @@ -1,10 +1,12 @@ +from rpython.rlib.objectmodel import we_are_translated from rpython.jit.metainterp.history import (AbstractFailDescr, ConstInt, INT, FLOAT, REF) from
[pypy-commit] pypy default: fix translation on arm
Author: Armin Rigo Branch: Changeset: r96810:c82849260828 Date: 2019-06-17 10:27 +0200 http://bitbucket.org/pypy/pypy/changeset/c82849260828/ Log:fix translation on arm diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -835,8 +835,9 @@ assert 0 def emit_op_load_effective_address(self, op, arglocs, regalloc, fcond): -self._gen_address(arglocs[4], arglocs[0], arglocs[1], arglocs[3].value, - arglocs[2].value) +static_ofs = op.getarg(2).getint() +scale = op.getarg(3).getint() +self._gen_address(arglocs[2], arglocs[0], arglocs[1], scale, static_ofs) return fcond # result = base_loc + (scaled_loc << scale) + static_offset diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py --- a/rpython/jit/backend/arm/regalloc.py +++ b/rpython/jit/backend/arm/regalloc.py @@ -902,7 +902,7 @@ arg0 = self.make_sure_var_in_reg(args[0], args) arg1 = self.make_sure_var_in_reg(args[1], args) res = self.force_allocate_reg(op) -return [arg0, arg1, args[2], args[3], res] +return [arg0, arg1, res] def prepare_op_call_malloc_nursery(self, op, fcond): size_box = op.getarg(0) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit