Author: fijal
Branch: str-measure
Changeset: r91221:9923d9d8b6c5
Date: 2017-05-10 16:17 +0200
http://bitbucket.org/pypy/pypy/changeset/9923d9d8b6c5/

Log:    a branch to start measuring how strings are used

diff --git a/pypy/interpreter/executioncontext.py 
b/pypy/interpreter/executioncontext.py
--- a/pypy/interpreter/executioncontext.py
+++ b/pypy/interpreter/executioncontext.py
@@ -153,6 +153,7 @@
         Like bytecode_trace() but doesn't invoke any other events besides the
         trace function.
         """
+        frame._frame_counter += 1
         if (frame.get_w_f_trace() is None or self.is_tracing or
             self.gettrace() is None):
             return
diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py
--- a/pypy/interpreter/pyframe.py
+++ b/pypy/interpreter/pyframe.py
@@ -76,6 +76,9 @@
     valuestackdepth = 0 # number of items on valuestack
     lastblock = None
 
+    # XXX string debugging
+    _frame_counter = 0
+
     # other fields:
     
     # builtin - builtin cache, only if honor__builtins__ is True
diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py
--- a/pypy/module/__pypy__/__init__.py
+++ b/pypy/module/__pypy__/__init__.py
@@ -98,6 +98,7 @@
         'decode_long'               : 'interp_magic.decode_long',
         '_promote'                   : 'interp_magic._promote',
         'stack_almost_full'         : 'interp_magic.stack_almost_full',
+        'set_str_debug_file'        : 'interp_debug.set_str_debug_file',
     }
     if sys.platform == 'win32':
         interpleveldefs['get_console_cp'] = 'interp_magic.get_console_cp'
diff --git a/pypy/module/__pypy__/interp_debug.py 
b/pypy/module/__pypy__/interp_debug.py
--- a/pypy/module/__pypy__/interp_debug.py
+++ b/pypy/module/__pypy__/interp_debug.py
@@ -28,3 +28,15 @@
 @jit.dont_look_inside
 def debug_flush(space):
     debug.debug_flush()
+
+class Cache(object):
+    def __init__(self, space):
+        self.w_debug_file = None
+
+def set_str_debug_file(space, w_debug_file):
+    if space.is_none(w_debug_file):
+        w_debug_file = None
+    space.fromcache(Cache).w_debug_file = w_debug_file
+
+def get_str_debug_file(space):
+    return space.fromcache(Cache).w_debug_file
\ No newline at end of file
diff --git a/pypy/objspace/std/bytearrayobject.py 
b/pypy/objspace/std/bytearrayobject.py
--- a/pypy/objspace/std/bytearrayobject.py
+++ b/pypy/objspace/std/bytearrayobject.py
@@ -50,15 +50,15 @@
     def nonmovable_carray(self, space):
         return BytearrayBuffer(self.data, False).get_raw_address()
 
-    def _new(self, value):
+    def _new(self, space, value):
         if value is self.data:
             value = value[:]
         return W_BytearrayObject(value)
 
-    def _new_from_buffer(self, buffer):
+    def _new_from_buffer(self, space, buffer):
         return W_BytearrayObject([buffer[i] for i in range(len(buffer))])
 
-    def _new_from_list(self, value):
+    def _new_from_list(self, space, value):
         return W_BytearrayObject(value)
 
     def _empty(self):
@@ -443,10 +443,10 @@
 
     def descr_add(self, space, w_other):
         if isinstance(w_other, W_BytearrayObject):
-            return self._new(self.data + w_other.data)
+            return self._new(space, self.data + w_other.data)
 
         if isinstance(w_other, W_BytesObject):
-            return self._add(self._op_val(space, w_other))
+            return self._add(space, self._op_val(space, w_other))
 
         try:
             buffer = _get_buffer(space, w_other)
@@ -454,11 +454,11 @@
             if e.match(space, space.w_TypeError):
                 return space.w_NotImplemented
             raise
-        return self._add(buffer)
+        return self._add(space, buffer)
 
-    @specialize.argtype(1)
-    def _add(self, other):
-        return self._new(self.data + [other[i] for i in range(len(other))])
+    @specialize.argtype(2)
+    def _add(self, space, other):
+        return self._new(space, self.data + [other[i] for i in 
range(len(other))])
 
     def descr_reverse(self, space):
         self.data.reverse()
diff --git a/pypy/objspace/std/bytesobject.py b/pypy/objspace/std/bytesobject.py
--- a/pypy/objspace/std/bytesobject.py
+++ b/pypy/objspace/std/bytesobject.py
@@ -481,10 +481,10 @@
                         "found", len(self._value))
         return space.newint(ord(self._value[0]))
 
-    def _new(self, value):
+    def _new(self, space, value):
         return W_BytesObject(value)
 
-    def _new_from_list(self, value):
+    def _new_from_list(self, space, value):
         return W_BytesObject(''.join(value))
 
     def _empty(self):
diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py
--- a/pypy/objspace/std/objspace.py
+++ b/pypy/objspace/std/objspace.py
@@ -361,7 +361,7 @@
     def newunicode(self, uni):
         assert uni is not None
         assert isinstance(uni, unicode)
-        return W_UnicodeObject(uni)
+        return W_UnicodeObject(self, uni)
 
     def type(self, w_obj):
         jit.promote(w_obj.__class__)
diff --git a/pypy/objspace/std/stringmethods.py 
b/pypy/objspace/std/stringmethods.py
--- a/pypy/objspace/std/stringmethods.py
+++ b/pypy/objspace/std/stringmethods.py
@@ -20,7 +20,7 @@
         #if start == 0 and stop == len(s) and space.is_w(space.type(orig_obj),
         #                                                space.w_bytes):
         #    return orig_obj
-        return self._new(s[start:stop])
+        return self._new(space, s[start:stop])
 
     def _convert_idx_params(self, space, w_start, w_end):
         value = self._val(space)
@@ -61,7 +61,7 @@
                 if e.match(space, space.w_TypeError):
                     return space.w_NotImplemented
                 raise
-            return self._new(self._val(space) + other)
+            return self._new(space, self._val(space) + other)
 
         # Bytearray overrides this method, CPython doesn't support contacting
         # buffers and strs, and unicodes are always handled above
@@ -77,8 +77,8 @@
         if times <= 0:
             return self._empty()
         if self._len() == 1:
-            return self._new(self._multi_chr(self._val(space)[0]) * times)
-        return self._new(self._val(space) * times)
+            return self._new(space, self._multi_chr(self._val(space)[0]) * 
times)
+        return self._new(space, self._val(space) * times)
 
     descr_rmul = descr_mul
 
@@ -94,7 +94,7 @@
                 return self._sliced(space, selfvalue, start, stop, self)
             else:
                 ret = _descr_getslice_slowpath(selfvalue, start, step, sl)
-                return self._new_from_list(ret)
+                return self._new_from_list(space, ret)
 
         index = space.getindex_w(w_index, space.w_IndexError, "string index")
         return self._getitem_result(space, index)
@@ -105,7 +105,7 @@
             character = selfvalue[index]
         except IndexError:
             raise oefmt(space.w_IndexError, "string index out of range")
-        return self._new(character)
+        return self._new(space, character)
 
     def descr_getslice(self, space, w_start, w_stop):
         selfvalue = self._val(space)
@@ -125,7 +125,7 @@
         builder.append(self._upper(value[0]))
         for i in range(1, len(value)):
             builder.append(self._lower(value[i]))
-        return self._new(builder.build())
+        return self._new(space, builder.build())
 
     @unwrap_spec(width=int, w_fillchar=WrappedDefault(' '))
     def descr_center(self, space, width, w_fillchar):
@@ -143,7 +143,7 @@
         else:
             centered = value
 
-        return self._new(centered)
+        return self._new(space, centered)
 
     def descr_count(self, space, w_sub, w_start=None, w_end=None):
         value, start, end = self._convert_idx_params(space, w_start, w_end)
@@ -207,7 +207,7 @@
                                                          tabsize) + token
             oldtoken = token
 
-        return self._new(expanded)
+        return self._new(space, expanded)
 
     def _tabindent(self, token, tabsize):
         """calculates distance behind the token to the next tabstop"""
@@ -442,7 +442,7 @@
             if value and i != 0:
                 sb.append(value)
             sb.append(unwrapped[i])
-        return self._new(sb.build())
+        return self._new(space, sb.build())
 
     def _join_autoconvert(self, space, list_w):
         assert False, 'unreachable'
@@ -459,7 +459,7 @@
             fillchar = self._multi_chr(fillchar[0])
             value = value + fillchar * d
 
-        return self._new(value)
+        return self._new(space, value)
 
     @unwrap_spec(width=int, w_fillchar=WrappedDefault(' '))
     def descr_rjust(self, space, width, w_fillchar):
@@ -473,14 +473,14 @@
             fillchar = self._multi_chr(fillchar[0])
             value = d * fillchar + value
 
-        return self._new(value)
+        return self._new(space, value)
 
     def descr_lower(self, space):
         value = self._val(space)
         builder = self._builder(len(value))
         for i in range(len(value)):
             builder.append(self._lower(value[i]))
-        return self._new(builder.build())
+        return self._new(space, builder.build())
 
     def descr_partition(self, space, w_sub):
         from pypy.objspace.std.bytearrayobject import W_BytearrayObject
@@ -501,11 +501,11 @@
 
             pos = find(value, sub, 0, len(value))
             if pos != -1 and isinstance(self, W_BytearrayObject):
-                w_sub = self._new_from_buffer(sub)
+                w_sub = self._new_from_buffer(space, sub)
 
         if pos == -1:
             if isinstance(self, W_BytearrayObject):
-                self = self._new(value)
+                self = self._new(space, value)
             return space.newtuple([self, self._empty(), self._empty()])
         else:
             return space.newtuple(
@@ -531,11 +531,11 @@
 
             pos = rfind(value, sub, 0, len(value))
             if pos != -1 and isinstance(self, W_BytearrayObject):
-                w_sub = self._new_from_buffer(sub)
+                w_sub = self._new_from_buffer(space, sub)
 
         if pos == -1:
             if isinstance(self, W_BytearrayObject):
-                self = self._new(value)
+                self = self._new(space, value)
             return space.newtuple([self._empty(), self._empty(), self])
         else:
             return space.newtuple(
@@ -557,7 +557,7 @@
         except OverflowError:
             raise oefmt(space.w_OverflowError, "replace string is too long")
 
-        return self._new(res)
+        return self._new(space, res)
 
     @unwrap_spec(maxsplit=int)
     def descr_split(self, space, w_sep=None, maxsplit=-1):
@@ -716,13 +716,13 @@
                 builder.append(self._upper(ch))
             else:
                 builder.append(ch)
-        return self._new(builder.build())
+        return self._new(space, builder.build())
 
     def descr_title(self, space):
         selfval = self._val(space)
         if len(selfval) == 0:
             return self
-        return self._new(self.title(selfval))
+        return self._new(space, self.title(selfval))
 
     @jit.elidable
     def title(self, value):
@@ -764,24 +764,24 @@
             for char in string:
                 if not deletion_table[ord(char)]:
                     buf.append(table[ord(char)])
-        return self._new(buf.build())
+        return self._new(space, buf.build())
 
     def descr_upper(self, space):
         value = self._val(space)
         builder = self._builder(len(value))
         for i in range(len(value)):
             builder.append(self._upper(value[i]))
-        return self._new(builder.build())
+        return self._new(space, builder.build())
 
     @unwrap_spec(width=int)
     def descr_zfill(self, space, width):
         selfval = self._val(space)
         if len(selfval) == 0:
-            return self._new(self._multi_chr(self._chr('0')) * width)
+            return self._new(space, self._multi_chr(self._chr('0')) * width)
         num_zeros = width - len(selfval)
         if num_zeros <= 0:
             # cannot return self, in case it is a subclass of str
-            return self._new(selfval)
+            return self._new(space, selfval)
 
         builder = self._builder(width)
         if len(selfval) > 0 and (selfval[0] == '+' or selfval[0] == '-'):
@@ -792,10 +792,10 @@
             start = 0
         builder.append_multiple_char(self._chr('0'), num_zeros)
         builder.append_slice(selfval, start, len(selfval))
-        return self._new(builder.build())
+        return self._new(space, builder.build())
 
     def descr_getnewargs(self, space):
-        return space.newtuple([self._new(self._val(space))])
+        return space.newtuple([self._new(space, self._val(space))])
 
 # ____________________________________________________________
 # helpers for slow paths, moved out because they contain loops
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
@@ -1,5 +1,6 @@
 """The builtin unicode implementation"""
 
+import py
 from rpython.rlib.objectmodel import (
     compute_hash, compute_unique_id, import_from_mixin,
     enforceargs)
@@ -29,11 +30,26 @@
 class W_UnicodeObject(W_Root):
     import_from_mixin(StringMethods)
     _immutable_fields_ = ['_value']
+    _frame_counter = 0
+    _frame_id = 0
 
     @enforceargs(uni=unicode)
-    def __init__(self, unistr):
+    def __init__(self, space, unistr):
         assert isinstance(unistr, unicode)
         self._value = unistr
+        if space is None:
+            return
+        frame = space.getexecutioncontext().gettopframe()
+        if frame is None:
+            return
+        self._frame_counter = frame._frame_counter
+        self._frame_id = compute_unique_id(frame)
+        from pypy.module.__pypy__.interp_debug import get_str_debug_file
+        w_file = get_str_debug_file(space)
+        if w_file is None:
+            return
+        space.call_function(space.getattr(w_file, space.newtext("write")),
+            space.newtext("descr_new %s %s\n" % (self._frame_counter, 
self._frame_id)))
 
     def __repr__(self):
         """representation for debugging purposes"""
@@ -43,10 +59,10 @@
         # for testing
         return self._value
 
-    def create_if_subclassed(self):
+    def create_if_subclassed(self, space):
         if type(self) is W_UnicodeObject:
             return self
-        return W_UnicodeObject(self._value)
+        return W_UnicodeObject(space, self._value)
 
     def is_w(self, space, w_other):
         if not isinstance(w_other, W_UnicodeObject):
@@ -105,11 +121,11 @@
                          "found", len(self._value))
         return space.newint(ord(self._value[0]))
 
-    def _new(self, value):
-        return W_UnicodeObject(value)
+    def _new(self, space, value):
+        return W_UnicodeObject(space, value)
 
-    def _new_from_list(self, value):
-        return W_UnicodeObject(u''.join(value))
+    def _new_from_list(self, space, value):
+        return W_UnicodeObject(space, u''.join(value))
 
     def _empty(self):
         return W_UnicodeObject.EMPTY
@@ -222,7 +238,7 @@
 
         assert isinstance(w_value, W_UnicodeObject)
         w_newobj = space.allocate_instance(W_UnicodeObject, w_unicodetype)
-        W_UnicodeObject.__init__(w_newobj, w_value._value)
+        W_UnicodeObject.__init__(w_newobj, space, w_value._value)
         return w_newobj
 
     def descr_repr(self, space):
@@ -354,7 +370,7 @@
                     raise oefmt(space.w_TypeError,
                                 "character mapping must return integer, None "
                                 "or unicode")
-        return W_UnicodeObject(u''.join(result))
+        return W_UnicodeObject(space, u''.join(result))
 
     def descr_encode(self, space, w_encoding=None, w_errors=None):
         encoding, errors = _get_encoding_and_errors(space, w_encoding,
@@ -420,7 +436,7 @@
 
 
 def wrapunicode(space, uni):
-    return W_UnicodeObject(uni)
+    return W_UnicodeObject(space, uni)
 
 
 def plain_str2unicode(space, s):
@@ -562,7 +578,7 @@
         return unicode_from_encoded_object(space, w_bytes, encoding, "strict")
     s = space.bytes_w(w_bytes)
     try:
-        return W_UnicodeObject(s.decode("ascii"))
+        return W_UnicodeObject(space, s.decode("ascii"))
     except UnicodeDecodeError:
         # raising UnicodeDecodeError is messy, "please crash for me"
         return unicode_from_encoded_object(space, w_bytes, "ascii", "strict")
@@ -967,6 +983,39 @@
         of the specified width. The string S is never truncated.
         """
 
+def setup():
+    from pypy.module.__pypy__.interp_debug import get_str_debug_file
+
+    def wrap(func):
+        d = {'orig': func, 'get_str_debug_file': get_str_debug_file}
+        name = func.__name__
+        orig_args = list(func.__code__.co_varnames[:func.__code__.co_argcount])
+        args = orig_args[:]
+        if func.func_defaults:
+            i = func.__code__.co_argcount - len(func.func_defaults)
+            for j, default in enumerate(func.func_defaults):
+                args[i] = "%s = %r" % (args[i], func.func_defaults[j])
+                i += 1
+        func_args = ", ".join(args)
+        lines = ["def %s(%s):" % (name, func_args),
+        "    w_file = get_str_debug_file(space)",
+        "    if w_file is not None:",
+        "        txt = '%s ' + str(self._frame_counter) + ' ' + 
str(self._frame_id) + ' '+ '\\n'" % func.func_name,
+        "        space.call_function(space.getattr(w_file, 
space.newtext('write')), space.newtext(txt))",
+        "    return orig(%s)" % (", ".join(orig_args),)]
+        exec "\n".join(lines) in d
+        if hasattr(func, 'unwrap_spec'):
+            d[name].unwrap_spec = func.unwrap_spec
+        # get it as an unbound method
+        return d[name]
+
+    for k, v in W_UnicodeObject.__dict__.iteritems():
+        if k == 'descr_new':
+            continue
+        if k.startswith('descr_'):
+           setattr(W_UnicodeObject, k, wrap(getattr(W_UnicodeObject, k)))
+
+setup()
 
 W_UnicodeObject.typedef = TypeDef(
     "unicode", basestring_typedef,
@@ -1112,7 +1161,7 @@
     return [s for s in value]
 
 
-W_UnicodeObject.EMPTY = W_UnicodeObject(u'')
+W_UnicodeObject.EMPTY = W_UnicodeObject(None, u'')
 
 
 # Helper for converting int/long
diff --git a/rpython/translator/platform/darwin.py 
b/rpython/translator/platform/darwin.py
--- a/rpython/translator/platform/darwin.py
+++ b/rpython/translator/platform/darwin.py
@@ -16,6 +16,7 @@
 
     standalone_only = ('-mdynamic-no-pic',)
     shared_only = ()
+    accepts_flto = False
 
     link_flags = (DARWIN_VERSION_MIN,)
     cflags = ('-O3', '-fomit-frame-pointer', DARWIN_VERSION_MIN)
diff --git a/rpython/translator/platform/posix.py 
b/rpython/translator/platform/posix.py
--- a/rpython/translator/platform/posix.py
+++ b/rpython/translator/platform/posix.py
@@ -11,6 +11,7 @@
     exe_ext = ''
     make_cmd = 'make'
     so_prefixes = ('lib', '')
+    accepts_flto = True
 
     relevant_environ = ('CPATH', 'LIBRARY_PATH', 'C_INCLUDE_PATH')
 
@@ -131,7 +132,7 @@
             cflags = tuple(self.cflags) + tuple(self.standalone_only)
 
         # xxx check which compilers accept this option or not
-        if not config or config.translation.gcrootfinder != 'asmgcc':
+        if (not config or config.translation.gcrootfinder != 'asmgcc') and 
self.accepts_flto:
             cflags = ('-flto',) + cflags
 
         m = GnuMakefile(path)
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to