~ubuntu-branches/debian/sid/meliae/sid

« back to all changes in this revision

Viewing changes to meliae/_scanner.pyx

  • Committer: Bazaar Package Importer
  • Author(s): Jelmer Vernooij
  • Date: 2009-12-19 18:23:37 UTC
  • Revision ID: james.westby@ubuntu.com-20091219182337-t09txw6ca1yfysn9
Tags: upstream-0.2.0
ImportĀ upstreamĀ versionĀ 0.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2009 Canonical Ltd
 
2
#
 
3
# This program is free software: you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License version 3 as
 
5
# published by the Free Software Foundation.
 
6
#
 
7
# This program is distributed in the hope that it will be useful, but
 
8
# WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
10
# General Public License for more details.
 
11
#
 
12
# You should have received a copy of the GNU General Public License
 
13
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
14
 
 
15
"""The core routines for scanning python references and dumping memory info."""
 
16
 
 
17
cdef extern from "stdio.h":
 
18
    ctypedef long size_t
 
19
    ctypedef struct FILE:
 
20
        pass
 
21
    FILE *stderr
 
22
    size_t fwrite(void *, size_t, size_t, FILE *)
 
23
    size_t fprintf(FILE *, char *, ...)
 
24
 
 
25
cdef extern from "Python.h":
 
26
    FILE *PyFile_AsFile(object)
 
27
    int Py_UNICODE_SIZE
 
28
    ctypedef struct PyGC_Head:
 
29
        pass
 
30
    object PyString_FromStringAndSize(char *, Py_ssize_t)
 
31
 
 
32
 
 
33
cdef extern from "_scanner_core.h":
 
34
    Py_ssize_t _size_of(object c_obj)
 
35
    ctypedef void (*write_callback)(void *callee_data, char *bytes, size_t len)
 
36
 
 
37
    void _clear_last_dumped()
 
38
    void _dump_object_info(write_callback write, void *callee_data,
 
39
                           object c_obj, object nodump, int recurse)
 
40
    object _get_referents(object c_obj)
 
41
 
 
42
 
 
43
_word_size = sizeof(Py_ssize_t)
 
44
_gc_head_size = sizeof(PyGC_Head)
 
45
_unicode_size = Py_UNICODE_SIZE
 
46
 
 
47
 
 
48
def size_of(obj):
 
49
    """Compute the size of the object.
 
50
 
 
51
    This is the actual malloc() size for this object, so for dicts it is the
 
52
    size of the dict object, plus the size of the array of references, but
 
53
    *not* the size of each individual referenced object.
 
54
 
 
55
    :param obj: The object to measure
 
56
    :return: An integer of the number of bytes used by this object.
 
57
    """
 
58
    return _size_of(obj)
 
59
 
 
60
 
 
61
cdef void _file_io_callback(void *callee_data, char *bytes, size_t len):
 
62
    cdef FILE *file_cb
 
63
    
 
64
    file_cb = <FILE *>callee_data
 
65
    fwrite(bytes, 1, len, file_cb)
 
66
 
 
67
 
 
68
cdef void _callable_callback(void *callee_data, char *bytes, size_t len):
 
69
    callable = <object>callee_data
 
70
 
 
71
    s = PyString_FromStringAndSize(bytes, len)
 
72
    callable(s)
 
73
 
 
74
 
 
75
def dump_object_info(object out, object obj, object nodump=None,
 
76
                     int recurse_depth=1):
 
77
    """Dump the object information to the given output.
 
78
 
 
79
    :param out: Either a File object, or a callable.
 
80
        If a File object, we will write bytes to the underlying FILE*
 
81
        Otherwise, we will call(str) with bytes as we build up the state of the
 
82
        object. Note that a single call will not be a complete description, but
 
83
        potentially a single character of the final formatted string.
 
84
    :param obj: The object to inspect
 
85
    :param nodump: If supplied, this is a set() of objects that we want to
 
86
        exclude from the dump file.
 
87
    :param recurse_depth: 0 to only dump the supplied object
 
88
       1 to dump the object and immediate neighbors that would not otherwise be
 
89
       referenced (such as strings).
 
90
       2 dump everything we find and continue recursing
 
91
    """
 
92
    cdef FILE *fp_out
 
93
 
 
94
    fp_out = PyFile_AsFile(out)
 
95
    if fp_out != NULL:
 
96
        # This must be a callable
 
97
        _dump_object_info(<write_callback>_file_io_callback, fp_out, obj,
 
98
                          nodump, recurse_depth)
 
99
    else:
 
100
        _dump_object_info(<write_callback>_callable_callback, <void *>out, obj,
 
101
                          nodump, recurse_depth)
 
102
    _clear_last_dumped()
 
103
 
 
104
 
 
105
def get_referents(object obj):
 
106
    """Similar to gc.get_referents()
 
107
 
 
108
    The main different is that gc.get_referents() only includes items that are
 
109
    in the garbage collector. However, we want anything referred to by
 
110
    tp_traverse.
 
111
    """
 
112
    return _get_referents(obj)