[pypy-commit] pypy py3.6: Optimise the common case for str to int conversion

2019-06-17 Thread rlamy
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

2019-06-17 Thread rlamy
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

2019-06-17 Thread fijal
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

2019-06-17 Thread fijal
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

2019-06-17 Thread arigo
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