-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
refcount.py
80 lines (67 loc) · 2.64 KB
/
refcount.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
"""
Helpers to see the refcount information of an object
"""
from llvmlite import ir
from numba.core import types, cgutils
from numba.core.extending import intrinsic
from numba.core.runtime.nrtdynmod import _meminfo_struct_type
@intrinsic
def dump_refcount(typingctx, obj):
"""Dump the refcount of an object to stdout.
Returns True if and only if object is reference-counted and NRT is enabled.
"""
def codegen(context, builder, signature, args):
[obj] = args
[ty] = signature.args
# A sequence of (type, meminfo)
meminfos = []
if context.enable_nrt:
tmp_mis = context.nrt.get_meminfos(builder, ty, obj)
meminfos.extend(tmp_mis)
if meminfos:
pyapi = context.get_python_api(builder)
gil_state = pyapi.gil_ensure()
pyapi.print_string("dump refct of {}".format(ty))
for ty, mi in meminfos:
miptr = builder.bitcast(mi, _meminfo_struct_type.as_pointer())
refctptr = cgutils.gep_inbounds(builder, miptr, 0, 0)
refct = builder.load(refctptr)
pyapi.print_string(" | {} refct=".format(ty))
# "%zu" is not portable. just truncate refcount to 32-bit.
# that's good enough for a debugging util.
refct_32bit = builder.trunc(refct, ir.IntType(32))
printed = cgutils.snprintf_stackbuffer(
builder, 30, "%d [%p]", refct_32bit, miptr
)
pyapi.sys_write_stdout(printed)
pyapi.print_string(";\n")
pyapi.gil_release(gil_state)
return cgutils.true_bit
else:
return cgutils.false_bit
sig = types.bool_(obj)
return sig, codegen
@intrinsic
def get_refcount(typingctx, obj):
"""Get the current refcount of an object.
FIXME: only handles the first object
"""
def codegen(context, builder, signature, args):
[obj] = args
[ty] = signature.args
# A sequence of (type, meminfo)
meminfos = []
if context.enable_nrt:
tmp_mis = context.nrt.get_meminfos(builder, ty, obj)
meminfos.extend(tmp_mis)
refcounts = []
if meminfos:
for ty, mi in meminfos:
miptr = builder.bitcast(mi, _meminfo_struct_type.as_pointer())
refctptr = cgutils.gep_inbounds(builder, miptr, 0, 0)
refct = builder.load(refctptr)
refct_32bit = builder.trunc(refct, ir.IntType(32))
refcounts.append(refct_32bit)
return refcounts[0]
sig = types.int32(obj)
return sig, codegen