Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
Pyston
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boxiang Sun
Pyston
Commits
600208d0
Commit
600208d0
authored
May 06, 2015
by
Chris Toshok
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #475 from toshok/stat-timers
Stat timers
parents
9405fb14
e2c4e221
Changes
28
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
28 changed files
with
890 additions
and
267 deletions
+890
-267
from_cpython/Include/pyconfig.h
from_cpython/Include/pyconfig.h
+3
-0
minibenchmarks/django-template.py
minibenchmarks/django-template.py
+115
-0
src/capi/descrobject.cpp
src/capi/descrobject.cpp
+1
-0
src/capi/typeobject.cpp
src/capi/typeobject.cpp
+29
-0
src/capi/types.h
src/capi/types.h
+3
-0
src/codegen/ast_interpreter.cpp
src/codegen/ast_interpreter.cpp
+5
-0
src/codegen/entry.cpp
src/codegen/entry.cpp
+1
-1
src/codegen/irgen/hooks.cpp
src/codegen/irgen/hooks.cpp
+6
-2
src/codegen/parser.cpp
src/codegen/parser.cpp
+2
-8
src/codegen/unwinding.cpp
src/codegen/unwinding.cpp
+2
-6
src/core/stats.cpp
src/core/stats.cpp
+158
-4
src/core/stats.h
src/core/stats.h
+82
-7
src/core/types.h
src/core/types.h
+13
-0
src/core/util.cpp
src/core/util.cpp
+18
-8
src/core/util.h
src/core/util.h
+12
-6
src/gc/collector.cpp
src/gc/collector.cpp
+2
-6
src/gc/gc_alloc.h
src/gc/gc_alloc.h
+9
-1
src/jit.cpp
src/jit.cpp
+191
-174
src/runtime/builtin_modules/builtins.cpp
src/runtime/builtin_modules/builtins.cpp
+4
-0
src/runtime/dict.cpp
src/runtime/dict.cpp
+8
-0
src/runtime/generator.cpp
src/runtime/generator.cpp
+39
-17
src/runtime/list.cpp
src/runtime/list.cpp
+2
-0
src/runtime/objmodel.cpp
src/runtime/objmodel.cpp
+109
-27
src/runtime/stacktrace.cpp
src/runtime/stacktrace.cpp
+1
-0
src/runtime/str.cpp
src/runtime/str.cpp
+3
-0
src/runtime/tuple.cpp
src/runtime/tuple.cpp
+2
-0
src/runtime/types.cpp
src/runtime/types.cpp
+9
-0
src/runtime/types.h
src/runtime/types.h
+61
-0
No files found.
from_cpython/Include/pyconfig.h
View file @
600208d0
...
...
@@ -59,6 +59,9 @@
#define HAVE_STRUCT_TM_TM_ZONE 1
#define HAVE_MKTIME 1
#define TIME_WITH_SYS_TIME
#define HAVE_GETTIMEOFDAY 1
#define PY_FORMAT_LONG_LONG "ll"
#define PY_FORMAT_SIZE_T "z"
...
...
minibenchmarks/django-template.py
0 → 100644
View file @
600208d0
from
django.template.base
import
Origin
,
Template
,
Context
,
TemplateDoesNotExist
from
django.conf
import
settings
from
django.apps
import
apps
import
time
try
:
import
__pyston__
pyston_loaded
=
True
except
:
pyston_loaded
=
False
template_source
=
"""
{% extends "admin/base_site.html" %}
{% load i18n admin_static %}
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/dashboard.css" %}" />{% endblock %}
{% block coltype %}colMS{% endblock %}
{% block bodyclass %}{{ block.super }} dashboard{% endblock %}
{% block breadcrumbs %}{% endblock %}
{% block content %}
<div id="content-main">
{% if app_list %}
{% for app in app_list %}
<div class="app-{{ app.app_label }} module">
<table>
<caption>
<a href="{{ app.app_url }}" class="section" title="{% blocktrans with name=app.name %}Models in the {{ name }} application{% endblocktrans %}">{{ app.name }}</a>
</caption>
{% for model in app.models %}
<tr class="model-{{ model.object_name|lower }}">
{% if model.admin_url %}
<th scope="row"><a href="{{ model.admin_url }}">{{ model.name }}</a></th>
{% else %}
<th scope="row">{{ model.name }}</th>
{% endif %}
{% if model.add_url %}
<td><a href="{{ model.add_url }}" class="addlink">{% trans 'Add' %}</a></td>
{% else %}
<td> </td>
{% endif %}
{% if model.admin_url %}
<td><a href="{{ model.admin_url }}" class="changelink">{% trans 'Change' %}</a></td>
{% else %}
<td> </td>
{% endif %}
</tr>
{% endfor %}
</table>
</div>
{% endfor %}
{% else %}
<p>{% trans "You don't have permission to edit anything." %}</p>
{% endif %}
</div>
{% endblock %}
{% block sidebar %}
<div id="content-related">
<div class="module" id="recent-actions-module">
<h2>{% trans 'Recent Actions' %}</h2>
<h3>{% trans 'My Actions' %}</h3>
{% load log %}
{% get_admin_log 10 as admin_log for_user user %}
{% if not admin_log %}
<p>{% trans 'None available' %}</p>
{% else %}
<ul class="actionlist">
{% for entry in admin_log %}
<li class="{% if entry.is_addition %}addlink{% endif %}{% if entry.is_change %}changelink{% endif %}{% if entry.is_deletion %}deletelink{% endif %}">
{% if entry.is_deletion or not entry.get_admin_url %}
{{ entry.object_repr }}
{% else %}
<a href="{{ entry.get_admin_url }}">{{ entry.object_repr }}</a>
{% endif %}
<br/>
{% if entry.content_type %}
<span class="mini quiet">{% filter capfirst %}{% trans entry.content_type.name %}{% endfilter %}</span>
{% else %}
<span class="mini quiet">{% trans 'Unknown content' %}</span>
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
</div>
</div>
{% endblock %}
"""
settings
.
configure
()
apps
.
populate
((
'django.contrib.admin'
,
'django.contrib.auth'
,
'django.contrib.contenttypes'
,
'django.contrib.sessions'
,
'django.contrib.messages'
,
'django.contrib.staticfiles'
,
))
elapsed
=
0
for
i
in
xrange
(
500
):
#if pyston_loaded:
# __pyston__.clearStats()
start
=
time
.
time
()
template
=
Template
(
template_source
,
None
,
"admin/index.html"
)
elapsed
=
time
.
time
()
-
start
print
"took %4.1fms for last iteration"
%
(
elapsed
*
1000.0
,)
src/capi/descrobject.cpp
View file @
600208d0
...
...
@@ -18,6 +18,7 @@
namespace
pyston
{
Box
*
BoxedMethodDescriptor
::
__call__
(
BoxedMethodDescriptor
*
self
,
Box
*
obj
,
BoxedTuple
*
varargs
,
Box
**
_args
)
{
STAT_TIMER
(
t0
,
"us_timer_boxedmethoddescriptor__call__"
);
BoxedDict
*
kwargs
=
static_cast
<
BoxedDict
*>
(
_args
[
0
]);
assert
(
self
->
cls
==
method_cls
);
...
...
src/capi/typeobject.cpp
View file @
600208d0
...
...
@@ -58,6 +58,7 @@ static int hackcheck(PyObject* self, setattrofunc func, const char* what) noexce
}
static
PyObject
*
wrap_setattr
(
PyObject
*
self
,
PyObject
*
args
,
void
*
wrapped
)
noexcept
{
STAT_TIMER
(
t0
,
"us_timer_wrap_setattr"
);
setattrofunc
func
=
(
setattrofunc
)
wrapped
;
int
res
;
PyObject
*
name
,
*
value
;
...
...
@@ -74,6 +75,7 @@ static PyObject* wrap_setattr(PyObject* self, PyObject* args, void* wrapped) noe
}
static
PyObject
*
wrap_delattr
(
PyObject
*
self
,
PyObject
*
args
,
void
*
wrapped
)
noexcept
{
STAT_TIMER
(
t0
,
"us_timer_wrap_delattr"
);
setattrofunc
func
=
(
setattrofunc
)
wrapped
;
int
res
;
PyObject
*
name
;
...
...
@@ -91,6 +93,7 @@ static PyObject* wrap_delattr(PyObject* self, PyObject* args, void* wrapped) noe
}
static
PyObject
*
wrap_hashfunc
(
PyObject
*
self
,
PyObject
*
args
,
void
*
wrapped
)
noexcept
{
STAT_TIMER
(
t0
,
"us_timer_wrap_hashfunc"
);
hashfunc
func
=
(
hashfunc
)
wrapped
;
long
res
;
...
...
@@ -103,12 +106,14 @@ static PyObject* wrap_hashfunc(PyObject* self, PyObject* args, void* wrapped) no
}
static
PyObject
*
wrap_call
(
PyObject
*
self
,
PyObject
*
args
,
void
*
wrapped
,
PyObject
*
kwds
)
noexcept
{
STAT_TIMER
(
t0
,
"us_timer_wrap_call"
);
ternaryfunc
func
=
(
ternaryfunc
)
wrapped
;
return
(
*
func
)(
self
,
args
,
kwds
);
}
static
PyObject
*
wrap_richcmpfunc
(
PyObject
*
self
,
PyObject
*
args
,
void
*
wrapped
,
int
op
)
noexcept
{
STAT_TIMER
(
t0
,
"us_timer_wrap_richcmpfunc"
);
richcmpfunc
func
=
(
richcmpfunc
)
wrapped
;
PyObject
*
other
;
...
...
@@ -132,6 +137,7 @@ RICHCMP_WRAPPER(gt, Py_GT)
RICHCMP_WRAPPER
(
ge
,
Py_GE
)
static
PyObject
*
wrap_next
(
PyObject
*
self
,
PyObject
*
args
,
void
*
wrapped
)
{
STAT_TIMER
(
t0
,
"us_timer_wrap_next"
);
unaryfunc
func
=
(
unaryfunc
)
wrapped
;
PyObject
*
res
;
...
...
@@ -144,6 +150,7 @@ static PyObject* wrap_next(PyObject* self, PyObject* args, void* wrapped) {
}
static
PyObject
*
wrap_descr_get
(
PyObject
*
self
,
PyObject
*
args
,
void
*
wrapped
)
noexcept
{
STAT_TIMER
(
t0
,
"us_timer_wrap_descr_get"
);
descrgetfunc
func
=
(
descrgetfunc
)
wrapped
;
PyObject
*
obj
;
PyObject
*
type
=
NULL
;
...
...
@@ -162,6 +169,7 @@ static PyObject* wrap_descr_get(PyObject* self, PyObject* args, void* wrapped) n
}
static
PyObject
*
wrap_coercefunc
(
PyObject
*
self
,
PyObject
*
args
,
void
*
wrapped
)
noexcept
{
STAT_TIMER
(
t0
,
"us_timer_wrap_coercefunc"
);
coercion
func
=
(
coercion
)
wrapped
;
PyObject
*
other
,
*
res
;
int
ok
;
...
...
@@ -188,6 +196,7 @@ static PyObject* wrap_coercefunc(PyObject* self, PyObject* args, void* wrapped)
}
static
PyObject
*
wrap_ternaryfunc
(
PyObject
*
self
,
PyObject
*
args
,
void
*
wrapped
)
noexcept
{
STAT_TIMER
(
t0
,
"us_timer_wrap_ternaryfunc"
);
ternaryfunc
func
=
(
ternaryfunc
)
wrapped
;
PyObject
*
other
;
PyObject
*
third
=
Py_None
;
...
...
@@ -200,6 +209,7 @@ static PyObject* wrap_ternaryfunc(PyObject* self, PyObject* args, void* wrapped)
}
static
PyObject
*
wrap_ternaryfunc_r
(
PyObject
*
self
,
PyObject
*
args
,
void
*
wrapped
)
noexcept
{
STAT_TIMER
(
t0
,
"us_timer_wrap_ternaryfunc_r"
);
ternaryfunc
func
=
(
ternaryfunc
)
wrapped
;
PyObject
*
other
;
PyObject
*
third
=
Py_None
;
...
...
@@ -212,6 +222,7 @@ static PyObject* wrap_ternaryfunc_r(PyObject* self, PyObject* args, void* wrappe
}
static
PyObject
*
wrap_unaryfunc
(
PyObject
*
self
,
PyObject
*
args
,
void
*
wrapped
)
noexcept
{
STAT_TIMER
(
t0
,
"us_timer_wrap_unaryfunc"
);
unaryfunc
func
=
(
unaryfunc
)
wrapped
;
if
(
!
check_num_args
(
args
,
0
))
...
...
@@ -220,6 +231,7 @@ static PyObject* wrap_unaryfunc(PyObject* self, PyObject* args, void* wrapped) n
}
static
PyObject
*
wrap_inquirypred
(
PyObject
*
self
,
PyObject
*
args
,
void
*
wrapped
)
noexcept
{
STAT_TIMER
(
t0
,
"us_timer_wrap_inquirypred"
);
inquiry
func
=
(
inquiry
)
wrapped
;
int
res
;
...
...
@@ -232,6 +244,7 @@ static PyObject* wrap_inquirypred(PyObject* self, PyObject* args, void* wrapped)
}
static
PyObject
*
wrapInquirypred
(
PyObject
*
self
,
PyObject
*
args
,
void
*
wrapped
)
{
STAT_TIMER
(
t0
,
"us_timer_wrapInquirypred"
);
inquiry
func
=
(
inquiry
)
wrapped
;
int
res
;
...
...
@@ -244,6 +257,7 @@ static PyObject* wrapInquirypred(PyObject* self, PyObject* args, void* wrapped)
}
static
PyObject
*
wrap_binaryfunc
(
PyObject
*
self
,
PyObject
*
args
,
void
*
wrapped
)
noexcept
{
STAT_TIMER
(
t0
,
"us_timer_wrap_binaryfunc"
);
binaryfunc
func
=
(
binaryfunc
)
wrapped
;
PyObject
*
other
;
...
...
@@ -254,6 +268,7 @@ static PyObject* wrap_binaryfunc(PyObject* self, PyObject* args, void* wrapped)
}
static
PyObject
*
wrap_binaryfunc_l
(
PyObject
*
self
,
PyObject
*
args
,
void
*
wrapped
)
noexcept
{
STAT_TIMER
(
t0
,
"us_timer_wrap_binaryfunc_l"
);
binaryfunc
func
=
(
binaryfunc
)
wrapped
;
PyObject
*
other
;
...
...
@@ -268,6 +283,7 @@ static PyObject* wrap_binaryfunc_l(PyObject* self, PyObject* args, void* wrapped
}
static
PyObject
*
wrap_binaryfunc_r
(
PyObject
*
self
,
PyObject
*
args
,
void
*
wrapped
)
noexcept
{
STAT_TIMER
(
t0
,
"us_timer_wrap_binaryfunc_r"
);
binaryfunc
func
=
(
binaryfunc
)
wrapped
;
PyObject
*
other
;
...
...
@@ -300,6 +316,7 @@ static Py_ssize_t getindex(PyObject* self, PyObject* arg) noexcept {
}
static
PyObject
*
wrap_lenfunc
(
PyObject
*
self
,
PyObject
*
args
,
void
*
wrapped
)
noexcept
{
STAT_TIMER
(
t0
,
"us_timer_wrap_lenfunc"
);
lenfunc
func
=
(
lenfunc
)
wrapped
;
Py_ssize_t
res
;
...
...
@@ -312,6 +329,7 @@ static PyObject* wrap_lenfunc(PyObject* self, PyObject* args, void* wrapped) noe
}
static
PyObject
*
wrap_indexargfunc
(
PyObject
*
self
,
PyObject
*
args
,
void
*
wrapped
)
noexcept
{
STAT_TIMER
(
t0
,
"us_timer_wrap_indexargfunc"
);
ssizeargfunc
func
=
(
ssizeargfunc
)
wrapped
;
PyObject
*
o
;
Py_ssize_t
i
;
...
...
@@ -325,6 +343,7 @@ static PyObject* wrap_indexargfunc(PyObject* self, PyObject* args, void* wrapped
}
static
PyObject
*
wrap_sq_item
(
PyObject
*
self
,
PyObject
*
args
,
void
*
wrapped
)
noexcept
{
STAT_TIMER
(
t0
,
"us_timer_wrap_sq_item"
);
ssizeargfunc
func
=
(
ssizeargfunc
)
wrapped
;
PyObject
*
arg
;
Py_ssize_t
i
;
...
...
@@ -342,6 +361,7 @@ static PyObject* wrap_sq_item(PyObject* self, PyObject* args, void* wrapped) noe
}
static
PyObject
*
wrap_ssizessizeargfunc
(
PyObject
*
self
,
PyObject
*
args
,
void
*
wrapped
)
noexcept
{
STAT_TIMER
(
t0
,
"us_timer_wrap_ssizessizeargfunc"
);
ssizessizeargfunc
func
=
(
ssizessizeargfunc
)
wrapped
;
Py_ssize_t
i
,
j
;
...
...
@@ -351,6 +371,7 @@ static PyObject* wrap_ssizessizeargfunc(PyObject* self, PyObject* args, void* wr
}
static
PyObject
*
wrap_sq_setitem
(
PyObject
*
self
,
PyObject
*
args
,
void
*
wrapped
)
noexcept
{
STAT_TIMER
(
t0
,
"us_timer_wrap_sq_setitem"
);
ssizeobjargproc
func
=
(
ssizeobjargproc
)
wrapped
;
Py_ssize_t
i
;
int
res
;
...
...
@@ -369,6 +390,7 @@ static PyObject* wrap_sq_setitem(PyObject* self, PyObject* args, void* wrapped)
}
static
PyObject
*
wrap_sq_delitem
(
PyObject
*
self
,
PyObject
*
args
,
void
*
wrapped
)
noexcept
{
STAT_TIMER
(
t0
,
"us_timer_wrap_sq_delitem"
);
ssizeobjargproc
func
=
(
ssizeobjargproc
)
wrapped
;
Py_ssize_t
i
;
int
res
;
...
...
@@ -388,6 +410,7 @@ static PyObject* wrap_sq_delitem(PyObject* self, PyObject* args, void* wrapped)
}
static
PyObject
*
wrap_ssizessizeobjargproc
(
PyObject
*
self
,
PyObject
*
args
,
void
*
wrapped
)
noexcept
{
STAT_TIMER
(
t0
,
"us_timer_wrap_ssizessizeobjargproc"
);
ssizessizeobjargproc
func
=
(
ssizessizeobjargproc
)
wrapped
;
Py_ssize_t
i
,
j
;
int
res
;
...
...
@@ -403,6 +426,7 @@ static PyObject* wrap_ssizessizeobjargproc(PyObject* self, PyObject* args, void*
}
static
PyObject
*
wrap_delslice
(
PyObject
*
self
,
PyObject
*
args
,
void
*
wrapped
)
noexcept
{
STAT_TIMER
(
t0
,
"us_timer_wrap_delslice"
);
ssizessizeobjargproc
func
=
(
ssizessizeobjargproc
)
wrapped
;
Py_ssize_t
i
,
j
;
int
res
;
...
...
@@ -418,6 +442,7 @@ static PyObject* wrap_delslice(PyObject* self, PyObject* args, void* wrapped) no
/* XXX objobjproc is a misnomer; should be objargpred */
static
PyObject
*
wrap_objobjproc
(
PyObject
*
self
,
PyObject
*
args
,
void
*
wrapped
)
noexcept
{
STAT_TIMER
(
t0
,
"us_timer_wrap_objobjproc"
);
objobjproc
func
=
(
objobjproc
)
wrapped
;
int
res
;
PyObject
*
value
;
...
...
@@ -433,6 +458,7 @@ static PyObject* wrap_objobjproc(PyObject* self, PyObject* args, void* wrapped)
}
static
PyObject
*
wrap_objobjargproc
(
PyObject
*
self
,
PyObject
*
args
,
void
*
wrapped
)
noexcept
{
STAT_TIMER
(
t0
,
"us_timer_wrap_objobjargproc"
);
objobjargproc
func
=
(
objobjargproc
)
wrapped
;
int
res
;
PyObject
*
key
,
*
value
;
...
...
@@ -447,6 +473,7 @@ static PyObject* wrap_objobjargproc(PyObject* self, PyObject* args, void* wrappe
}
static
PyObject
*
wrap_delitem
(
PyObject
*
self
,
PyObject
*
args
,
void
*
wrapped
)
noexcept
{
STAT_TIMER
(
t0
,
"us_timer_wrap_delitem"
);
objobjargproc
func
=
(
objobjargproc
)
wrapped
;
int
res
;
PyObject
*
key
;
...
...
@@ -462,6 +489,7 @@ static PyObject* wrap_delitem(PyObject* self, PyObject* args, void* wrapped) noe
}
static
PyObject
*
wrap_cmpfunc
(
PyObject
*
self
,
PyObject
*
args
,
void
*
wrapped
)
noexcept
{
STAT_TIMER
(
t0
,
"us_timer_wrap_cmpfunc"
);
cmpfunc
func
=
(
cmpfunc
)
wrapped
;
int
res
;
PyObject
*
other
;
...
...
@@ -482,6 +510,7 @@ static PyObject* wrap_cmpfunc(PyObject* self, PyObject* args, void* wrapped) noe
static
PyObject
*
wrap_init
(
PyObject
*
self
,
PyObject
*
args
,
void
*
wrapped
,
PyObject
*
kwds
)
noexcept
{
STAT_TIMER
(
t0
,
"us_timer_wrap_init"
);
initproc
func
=
(
initproc
)
wrapped
;
if
(
func
(
self
,
args
,
kwds
)
<
0
)
...
...
src/capi/types.h
View file @
600208d0
...
...
@@ -54,6 +54,7 @@ public:
}
static
Box
*
__call__
(
BoxedCApiFunction
*
self
,
BoxedTuple
*
varargs
,
BoxedDict
*
kwargs
)
{
STAT_TIMER
(
t0
,
"us_timer_boxedcapifunction__call__"
);
assert
(
self
->
cls
==
capifunc_cls
);
assert
(
varargs
->
cls
==
tuple_cls
);
assert
(
kwargs
->
cls
==
dict_cls
);
...
...
@@ -111,6 +112,8 @@ public:
DEFAULT_CLASS
(
wrapperobject_cls
);
static
Box
*
__call__
(
BoxedWrapperObject
*
self
,
Box
*
args
,
Box
*
kwds
)
{
STAT_TIMER
(
t0
,
"us_timer_boxedwrapperobject__call__"
);
assert
(
self
->
cls
==
wrapperobject_cls
);
assert
(
args
->
cls
==
tuple_cls
);
assert
(
kwds
->
cls
==
dict_cls
);
...
...
src/codegen/ast_interpreter.cpp
View file @
600208d0
...
...
@@ -284,6 +284,8 @@ public:
Value
ASTInterpreter
::
execute
(
ASTInterpreter
&
interpreter
,
CFGBlock
*
start_block
,
AST_stmt
*
start_at
)
{
threading
::
allowGLReadPreemption
();
STAT_TIMER
(
t0
,
"us_timer_astinterpreter_execute"
);
void
*
frame_addr
=
__builtin_frame_address
(
0
);
RegisterHelper
frame_registerer
(
&
interpreter
,
frame_addr
);
...
...
@@ -540,6 +542,7 @@ Value ASTInterpreter::visit_jump(AST_Jump* node) {
arg_array
.
push_back
(
it
.
second
);
}
STAT_TIMER
(
t0
,
"us_timer_astinterpreter_jump_osrexit"
);
CompiledFunction
*
partial_func
=
compilePartialFuncInternal
(
&
exit
);
auto
arg_tuple
=
getTupleFromArgsArray
(
&
arg_array
[
0
],
arg_array
.
size
());
Box
*
r
=
partial_func
->
call
(
std
::
get
<
0
>
(
arg_tuple
),
std
::
get
<
1
>
(
arg_tuple
),
std
::
get
<
2
>
(
arg_tuple
),
...
...
@@ -927,6 +930,8 @@ Value ASTInterpreter::visit_print(AST_Print* node) {
static
const
std
::
string
newline_str
(
"
\n
"
);
static
const
std
::
string
space_str
(
" "
);
STAT_TIMER
(
t0
,
"us_timer_visit_print"
);
Box
*
dest
=
node
->
dest
?
visit_expr
(
node
->
dest
).
o
:
getSysStdout
();
int
nvals
=
node
->
values
.
size
();
assert
(
nvals
<=
1
&&
"cfg should have lowered it to 0 or 1 values"
);
...
...
src/codegen/entry.cpp
View file @
600208d0
...
...
@@ -362,7 +362,7 @@ static void handle_sigint(int signum) {
// For now, just call abort(), so that we get a traceback at least.
fprintf
(
stderr
,
"SIGINT!
\n
"
);
joinRuntime
();
Stats
::
dump
();
Stats
::
dump
(
false
);
abort
();
}
...
...
src/codegen/irgen/hooks.cpp
View file @
600208d0
...
...
@@ -182,6 +182,7 @@ static void compileIR(CompiledFunction* cf, EffortLevel effort) {
// The codegen_lock needs to be held in W mode before calling this function:
CompiledFunction
*
compileFunction
(
CLFunction
*
f
,
FunctionSpecialization
*
spec
,
EffortLevel
effort
,
const
OSREntryDescriptor
*
entry_descriptor
)
{
STAT_TIMER
(
t0
,
"us_timer_compileFunction"
);
Timer
_t
(
"for compileFunction()"
,
1000
);
assert
((
entry_descriptor
!=
NULL
)
+
(
spec
!=
NULL
)
==
1
);
...
...
@@ -315,10 +316,13 @@ void compileAndRunModule(AST_Module* m, BoxedModule* bm) {
assert
(
cf
->
clfunc
->
versions
.
size
());
}
if
(
cf
->
is_interpreted
)
if
(
cf
->
is_interpreted
)
{
STAT_TIMER
(
t0
,
"us_timer_interpreted_module_toplevel"
);
astInterpretFunction
(
cf
,
0
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
);
else
}
else
{
STAT_TIMER
(
t1
,
"us_timer_jitted_module_toplevel"
);
((
void
(
*
)())
cf
->
code
)();
}
}
Box
*
evalOrExec
(
CLFunction
*
cl
,
Box
*
globals
,
Box
*
boxedLocals
)
{
...
...
src/codegen/parser.cpp
View file @
600208d0
...
...
@@ -982,7 +982,7 @@ AST_Module* parse_string(const char* code) {
}
AST_Module
*
parse_file
(
const
char
*
fn
)
{
Timer
_t
(
"
parsing"
);
STAT_TIMER
(
t0
,
"us_timer_cpyton_
parsing"
);
if
(
ENABLE_PYPA_PARSER
)
{
AST_Module
*
rtn
=
pypa_parse
(
fn
);
...
...
@@ -1003,10 +1003,6 @@ AST_Module* parse_file(const char* fn) {
assert
(
rtn
->
type
==
AST_TYPE
::
Module
);
long
us
=
_t
.
end
();
static
StatCounter
us_parsing
(
"us_parsing"
);
us_parsing
.
log
(
us
);
return
ast_cast
<
AST_Module
>
(
rtn
);
}
...
...
@@ -1071,9 +1067,7 @@ static ParseResult _reparse(const char* fn, const std::string& cache_fn, AST_Mod
// it's not a huge deal right now, but this caching version can significantly cut down
// on the startup time (40ms -> 10ms).
AST_Module
*
caching_parse_file
(
const
char
*
fn
)
{
static
StatCounter
us_parsing
(
"us_parsing"
);
Timer
_t
(
"parsing"
);
_t
.
setExitCallback
([](
long
t
)
{
us_parsing
.
log
(
t
);
});
STAT_TIMER
(
t0
,
"us_timer_caching_parse_file"
);
int
code
;
std
::
string
cache_fn
=
std
::
string
(
fn
)
+
"c"
;
...
...
src/codegen/unwinding.cpp
View file @
600208d0
...
...
@@ -494,6 +494,7 @@ void unwindPythonStack(std::function<bool(std::unique_ptr<PythonFrameIteratorImp
}
static
std
::
unique_ptr
<
PythonFrameIteratorImpl
>
getTopPythonFrame
()
{
STAT_TIMER
(
t0
,
"us_timer_getTopPythonFrame"
);
std
::
unique_ptr
<
PythonFrameIteratorImpl
>
rtn
(
nullptr
);
unwindPythonStack
([
&
](
std
::
unique_ptr
<
PythonFrameIteratorImpl
>
iter
)
{
rtn
=
std
::
move
(
iter
);
...
...
@@ -512,8 +513,8 @@ static const LineInfo* lineInfoForFrame(PythonFrameIteratorImpl& frame_it) {
return
new
LineInfo
(
current_stmt
->
lineno
,
current_stmt
->
col_offset
,
source
->
fn
,
source
->
getName
());
}
static
StatCounter
us_gettraceback
(
"us_gettraceback"
);
BoxedTraceback
*
getTraceback
()
{
STAT_TIMER
(
t0
,
"us_timer_gettraceback"
);
if
(
!
ENABLE_FRAME_INTROSPECTION
)
{
static
bool
printed_warning
=
false
;
if
(
!
printed_warning
)
{
...
...
@@ -532,8 +533,6 @@ BoxedTraceback* getTraceback() {
return
new
BoxedTraceback
();
}
Timer
_t
(
"getTraceback"
,
1000
);
std
::
vector
<
const
LineInfo
*>
entries
;
unwindPythonStack
([
&
](
std
::
unique_ptr
<
PythonFrameIteratorImpl
>
frame_iter
)
{
const
LineInfo
*
line_info
=
lineInfoForFrame
(
*
frame_iter
.
get
());
...
...
@@ -544,9 +543,6 @@ BoxedTraceback* getTraceback() {
std
::
reverse
(
entries
.
begin
(),
entries
.
end
());
long
us
=
_t
.
end
();
us_gettraceback
.
log
(
us
);
return
new
BoxedTraceback
(
std
::
move
(
entries
));
}
...
...
src/core/stats.cpp
View file @
600208d0
...
...
@@ -22,9 +22,108 @@
namespace
pyston
{
#if !DISABLE_STATS
std
::
vector
<
long
>*
Stats
::
counts
;
extern
"C"
const
char
*
getStatTimerNameById
(
int
id
)
{
return
Stats
::
getStatName
(
id
).
c_str
();
}
extern
"C"
int
getStatTimerId
()
{
return
StatTimer
::
getStack
()
->
getId
();
}
extern
"C"
const
char
*
getStatTimerName
()
{
return
getStatTimerNameById
(
getStatTimerId
());
}
__thread
StatTimer
*
StatTimer
::
stack
;
StatTimer
::
StatTimer
(
int
statid
,
bool
push
)
{
uint64_t
at_time
=
getCPUTicks
();
_duration
=
0
;
_start_time
=
0
;
_statid
=
statid
;
if
(
!
push
)
{
_prev
=
NULL
;
return
;
}
_prev
=
stack
;
stack
=
this
;
if
(
_prev
)
{
_prev
->
pause
(
at_time
);
}
resume
(
at_time
);
}
StatTimer
::
StatTimer
(
int
statid
,
uint64_t
at_time
)
{
_duration
=
0
;
_start_time
=
0
;
_statid
=
statid
;
_prev
=
stack
;
stack
=
this
;
if
(
_prev
)
{
_prev
->
pause
(
at_time
);
}
resume
(
at_time
);
}
StatTimer
::~
StatTimer
()
{
assert
(
stack
==
this
);
uint64_t
at_time
;
if
(
!
isPaused
())
{
at_time
=
getCPUTicks
();
pause
(
at_time
);
}
else
{
// fprintf (stderr, "WARNING: timer was paused.\n");
at_time
=
_last_pause_time
;
}
stack
=
_prev
;
if
(
stack
)
{
stack
->
resume
(
at_time
);
}
}
void
StatTimer
::
pause
(
uint64_t
at_time
)
{
assert
(
!
isPaused
());
assert
(
at_time
>
_start_time
);
auto
cur_duration
=
_duration
;
_duration
=
at_time
-
_start_time
;
assert
(
_duration
>
cur_duration
);
Stats
::
log
(
_statid
,
_duration
);
_duration
=
0
;
_start_time
=
0
;
_last_pause_time
=
at_time
;
// fprintf (stderr, "paused %d at %lu\n", _statid, at_time);
}
void
StatTimer
::
resume
(
uint64_t
at_time
)
{
assert
(
isPaused
());
_start_time
=
at_time
;
// fprintf (stderr, "resumed %d at %lu\n", _statid, at_time);
}
StatTimer
*
StatTimer
::
swapStack
(
StatTimer
*
s
,
uint64_t
at_time
)
{
StatTimer
*
prev_stack
=
stack
;
if
(
stack
)
{
stack
->
pause
(
at_time
);
}
stack
=
s
;
if
(
stack
)
{
stack
->
resume
(
at_time
);
}
return
prev_stack
;
}
std
::
vector
<
uint64_t
>*
Stats
::
counts
;
std
::
unordered_map
<
int
,
std
::
string
>*
Stats
::
names
;
bool
Stats
::
enabled
;
timespec
Stats
::
start_ts
;
uint64_t
Stats
::
start_tick
;
StatCounter
::
StatCounter
(
const
std
::
string
&
name
)
:
id
(
Stats
::
getStatId
(
name
))
{
}
...
...
@@ -38,7 +137,7 @@ int Stats::getStatId(const std::string& name) {
// hacky but easy way of getting around static constructor ordering issues for now:
static
std
::
unordered_map
<
int
,
std
::
string
>
names
;
Stats
::
names
=
&
names
;
static
std
::
vector
<
long
>
counts
;
static
std
::
vector
<
uint64_t
>
counts
;
Stats
::
counts
=
&
counts
;
static
std
::
unordered_map
<
std
::
string
,
int
>
made
;
...
...
@@ -52,11 +151,36 @@ int Stats::getStatId(const std::string& name) {
return
rtn
;
}
std
::
string
Stats
::
getStatName
(
int
id
)
{
return
(
*
names
)[
id
];
}
void
Stats
::
startEstimatingCPUFreq
()
{
if
(
!
Stats
::
enabled
)
return
;
clock_gettime
(
CLOCK_REALTIME
,
&
Stats
::
start_ts
);
Stats
::
start_tick
=
getCPUTicks
();
}
// returns our estimate of the MHz of the cpu. MHz is handy because we're mostly interested in microsoecond-resolution
// timing.
double
Stats
::
estimateCPUFreq
()
{
timespec
dump_ts
;
clock_gettime
(
CLOCK_REALTIME
,
&
dump_ts
);
uint64_t
end_tick
=
getCPUTicks
();
uint64_t
wall_clock_ns
=
(
dump_ts
.
tv_sec
-
start_ts
.
tv_sec
)
*
1000000000
+
(
dump_ts
.
tv_nsec
-
start_ts
.
tv_nsec
);
return
(
double
)(
end_tick
-
Stats
::
start_tick
)
*
1000
/
wall_clock_ns
;
}
void
Stats
::
dump
(
bool
includeZeros
)
{
if
(
!
Stats
::
enabled
)
return
;
double
cycles_per_us
=
Stats
::
estimateCPUFreq
();
fprintf
(
stderr
,
"Stats:
\n
"
);
fprintf
(
stderr
,
"estimated_cpu_mhz: %5.5f
\n
"
,
cycles_per_us
);
gc
::
dumpHeapStatistics
(
0
);
...
...
@@ -69,11 +193,41 @@ void Stats::dump(bool includeZeros) {
std
::
sort
(
pairs
.
begin
(),
pairs
.
end
());
uint64_t
ticks_in_main
=
0
;
uint64_t
accumulated_stat_timer_ticks
=
0
;
for
(
int
i
=
0
;
i
<
pairs
.
size
();
i
++
)
{
if
(
includeZeros
||
(
*
counts
)[
pairs
[
i
].
second
]
>
0
)
fprintf
(
stderr
,
"%s: %ld
\n
"
,
pairs
[
i
].
first
.
c_str
(),
(
*
counts
)[
pairs
[
i
].
second
]);
if
(
includeZeros
||
(
*
counts
)[
pairs
[
i
].
second
]
>
0
)
{
if
(
startswith
(
pairs
[
i
].
first
,
"us_"
)
||
startswith
(
pairs
[
i
].
first
,
"_init_us_"
))
{
fprintf
(
stderr
,
"%s: %lu
\n
"
,
pairs
[
i
].
first
.
c_str
(),
(
uint64_t
)((
*
counts
)[
pairs
[
i
].
second
]
/
cycles_per_us
));
}
else
fprintf
(
stderr
,
"%s: %lu
\n
"
,
pairs
[
i
].
first
.
c_str
(),
(
*
counts
)[
pairs
[
i
].
second
]);
if
(
startswith
(
pairs
[
i
].
first
,
"us_timer_"
))
accumulated_stat_timer_ticks
+=
(
*
counts
)[
pairs
[
i
].
second
];
if
(
pairs
[
i
].
first
==
"ticks_in_main"
)
ticks_in_main
=
(
*
counts
)[
pairs
[
i
].
second
];
}
}
if
(
includeZeros
||
accumulated_stat_timer_ticks
>
0
)
fprintf
(
stderr
,
"ticks_all_timers: %lu
\n
"
,
accumulated_stat_timer_ticks
);
#if 0
// I want to enable this, but am leaving it disabled for the time
// being because it causes test failures due to:
//
// 1) some tests exit from main from inside catch blocks, without
// going through the logic to stop the timers.
// 2) some tests create multiple threads which causes problems
// with our non-per thread stat timers.
if (ticks_in_main && ticks_in_main != accumulated_stat_timer_ticks) {
fprintf(stderr, "WARNING: accumulated stat timer ticks != ticks in main - don't trust timer output.");
}
#endif
fprintf
(
stderr
,
"(End of stats)
\n
"
);
}
...
...
src/core/stats.h
View file @
600208d0
...
...
@@ -22,23 +22,48 @@
#include <vector>
#include "core/options.h"
#include "core/util.h"
namespace
pyston
{
#define STAT_ALLOCATIONS 0
#define DISABLE_STATS 0
#if !DISABLE_STATS
#define STAT_TIMER(id, name) \
static int _stid##id = Stats::getStatId(name); \
StatTimer _st##id(_stid##id)
#define STAT_TIMER2(id, name, at_time) \
static int _stid##id = Stats::getStatId(name); \
StatTimer _st##id(_stid##id, at_time)
#else
#define STAT_TIMER(id, name) StatTimer _st##id(0);
#define STAT_TIMER2(id, name, at_time) StatTimer _st##id(0);
#endif
#define STAT_TIMER_NAME(id) _st##id
#if !DISABLE_STATS
struct
Stats
{
private:
static
std
::
vector
<
long
>*
counts
;
static
std
::
vector
<
uint64_t
>*
counts
;
static
std
::
unordered_map
<
int
,
std
::
string
>*
names
;
static
bool
enabled
;
static
timespec
start_ts
;
static
uint64_t
start_tick
;
public:
static
void
startEstimatingCPUFreq
();
static
double
estimateCPUFreq
();
static
int
getStatId
(
const
std
::
string
&
name
);
static
std
::
string
getStatName
(
int
id
);
static
void
setEnabled
(
bool
enabled
)
{
Stats
::
enabled
=
enabled
;
}
static
void
log
(
int
id
,
in
t
count
=
1
)
{
(
*
counts
)[
id
]
+=
count
;
}
static
void
log
(
int
id
,
uint64_
t
count
=
1
)
{
(
*
counts
)[
id
]
+=
count
;
}
static
void
clear
()
{
std
::
fill
(
counts
->
begin
(),
counts
->
end
(),
0
);
}
static
void
dump
(
bool
includeZeros
=
true
);
...
...
@@ -52,7 +77,41 @@ private:
public:
StatCounter
(
const
std
::
string
&
name
);
void
log
(
int
count
=
1
)
{
Stats
::
log
(
id
,
count
);
}
void
log
(
uint64_t
count
=
1
)
{
Stats
::
log
(
id
,
count
);
}
};
class
StatTimer
{
private:
static
__thread
StatTimer
*
stack
;
// the accumulated active duration of this timer
uint64_t
_duration
;
// the start time of the current active segment (0 == paused)
uint64_t
_start_time
;
uint64_t
_last_pause_time
;
StatTimer
*
_prev
;
int
_statid
;
public:
StatTimer
(
int
statid
,
bool
push
=
true
);
StatTimer
(
int
statid
,
uint64_t
at_time
);
~
StatTimer
();
void
pause
(
uint64_t
at_time
);
void
resume
(
uint64_t
at_time
);
bool
isPaused
()
const
{
return
_start_time
==
0
;
}
int
getId
()
const
{
return
_statid
;
}
static
StatTimer
*
getStack
()
{
return
stack
;
}
static
StatTimer
*
swapStack
(
StatTimer
*
s
,
uint64_t
at_time
);
static
void
assertActive
()
{
RELEASE_ASSERT
(
stack
&&
!
stack
->
isPaused
(),
""
);
}
};
struct
StatPerThreadCounter
{
...
...
@@ -62,24 +121,40 @@ private:
public:
StatPerThreadCounter
(
const
std
::
string
&
name
);
void
log
(
in
t
count
=
1
)
{
Stats
::
log
(
id
,
count
);
}
void
log
(
uint64_
t
count
=
1
)
{
Stats
::
log
(
id
,
count
);
}
};
#else
struct
Stats
{
static
void
startEstimatingCPUFreq
()
{}
static
double
estimateCPUFreq
()
{
return
0
;
}
static
void
setEnabled
(
bool
enabled
)
{}
static
void
dump
()
{
printf
(
"(Stats disabled)
\n
"
);
}
static
void
dump
(
bool
includeZeros
=
true
)
{
printf
(
"(Stats disabled)
\n
"
);
}
static
void
clear
()
{}
static
void
log
(
int
id
,
int
count
=
1
)
{}
static
int
getStatId
(
const
std
::
string
&
name
)
{
return
0
;
}
static
void
endOfInit
()
{}
};
struct
StatCounter
{
StatCounter
(
const
char
*
name
)
{}
void
log
(
int
count
=
1
){};
void
log
(
uint64_t
count
=
1
){};
};
struct
StatTimer
{
StatTimer
(
int
statid
,
bool
push
=
true
)
{}
StatTimer
(
int
statid
,
uint64_t
at_time
)
{}
~
StatTimer
()
{}
bool
isPaused
()
const
{
return
false
;
}
void
pause
(
uint64_t
at_time
)
{}
void
resume
(
uint64_t
at_time
)
{}
static
StatTimer
*
getStack
()
{
return
NULL
;
}
static
StatTimer
*
swapStack
(
StatTimer
*
s
,
uint64_t
at_time
)
{
return
NULL
;
}
static
void
assertActive
()
{}
};
struct
StatPerThreadCounter
{
StatPerThreadCounter
(
const
char
*
name
)
{}
void
log
(
in
t
count
=
1
){};
void
log
(
uint64_
t
count
=
1
){};
};
#endif
}
...
...
src/core/types.h
View file @
600208d0
...
...
@@ -485,13 +485,26 @@ extern "C" PyObject* PystonType_GenericAlloc(BoxedClass* cls, Py_ssize_t nitems)
return Box::operator new(size, default_cls); \
}
#if STAT_ALLOCATIONS
#define ALLOC_STATS(cls) \
std::string per_name_alloc_name = "alloc." + std::string(cls->tp_name); \
std::string per_name_allocsize_name = "allocsize." + std::string(cls->tp_name); \
Stats::log(Stats::getStatId(per_name_alloc_name)); \
Stats::log(Stats::getStatId(per_name_allocsize_name), size);
#else
#define ALLOC_STATS(cls)
#endif
// The restrictions on when you can use the SIMPLE (ie fast) variant are encoded as
// asserts in the 1-arg operator new function:
#define DEFAULT_CLASS_SIMPLE(default_cls) \
void* operator new(size_t size, BoxedClass * cls) __attribute__((visibility("default"))) { \
ALLOC_STATS(cls); \
return Box::operator new(size, cls); \
} \
void* operator new(size_t size) __attribute__((visibility("default"))) { \
ALLOC_STATS(default_cls); \
/* In the simple cases, we can inline the following methods and simplify things a lot: \
* - Box::operator new \
* - cls->tp_alloc \
...
...
src/core/util.cpp
View file @
600208d0
...
...
@@ -16,6 +16,9 @@
#include <cstdio>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <string>
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FormattedStream.h"
...
...
@@ -26,6 +29,11 @@
namespace
pyston
{
uint64_t
getCPUTicks
()
{
unsigned
int
_unused
;
return
__rdtscp
(
&
_unused
);
}
int
Timer
::
level
=
0
;
Timer
::
Timer
(
const
char
*
desc
,
long
min_usec
)
:
min_usec
(
min_usec
),
ended
(
true
)
{
...
...
@@ -36,7 +44,7 @@ void Timer::restart(const char* newdesc) {
assert
(
ended
);
desc
=
newdesc
;
gettimeofday
(
&
start_time
,
NULL
);
start_time
=
getCPUTicks
(
);
Timer
::
level
++
;
ended
=
false
;
}
...
...
@@ -46,14 +54,14 @@ void Timer::restart(const char* newdesc, long new_min_usec) {
restart
(
newdesc
);
}
long
Timer
::
end
(
)
{
uint64_t
Timer
::
end
(
uint64_t
*
ended_at
)
{
if
(
!
ended
)
{
timeval
end
;
gettimeofday
(
&
end
,
NULL
);
long
us
=
1000000L
*
(
end
.
tv_sec
-
start_time
.
tv_sec
)
+
(
end
.
tv_usec
-
start_time
.
tv_usec
);
uint64_t
end
=
getCPUTicks
();
uint64_t
duration
=
end
-
start_time
;
Timer
::
level
--
;
if
(
VERBOSITY
(
"time"
)
>=
2
&&
desc
)
{
uint64_t
us
=
(
uint64_t
)(
duration
/
Stats
::
estimateCPUFreq
());
if
(
us
>
min_usec
)
{
for
(
int
i
=
0
;
i
<
Timer
::
level
;
i
++
)
{
putchar
(
' '
);
...
...
@@ -70,15 +78,17 @@ long Timer::end() {
fflush
(
stdout
);
}
}
if
(
ended_at
)
*
ended_at
=
end
;
ended
=
true
;
return
us
;
return
duration
;
}
return
-
1
;
}
Timer
::~
Timer
()
{
if
(
!
ended
)
{
long
t
=
end
();
uint64_t
t
=
end
();
if
(
exit_callback
)
exit_callback
(
t
);
}
...
...
src/core/util.h
View file @
600208d0
...
...
@@ -24,30 +24,36 @@
namespace
pyston
{
uint64_t
getCPUTicks
();
class
Timer
{
private:
static
int
level
;
timeval
start_time
;
uint64_t
start_time
;
const
char
*
desc
;
long
min_usec
;
bool
ended
;
std
::
function
<
void
(
long
)
>
exit_callback
;
std
::
function
<
void
(
uint64_t
)
>
exit_callback
;
public:
Timer
(
const
char
*
desc
=
NULL
,
long
min_usec
=
-
1
);
~
Timer
();
void
setExitCallback
(
std
::
function
<
void
(
long
)
>
_exit_callback
)
{
exit_callback
=
_exit_callback
;
}
void
setExitCallback
(
std
::
function
<
void
(
uint64_t
)
>
_exit_callback
)
{
exit_callback
=
_exit_callback
;
}
void
restart
(
const
char
*
newdesc
,
long
new_min_usec
);
void
restart
(
const
char
*
newdesc
=
NULL
);
long
end
();
long
split
(
const
char
*
newdesc
=
NULL
)
{
long
rtn
=
end
();
// returns the duration. if @ended_at is non-null, it's filled in
// with the tick the timer stopped at.
uint64_t
end
(
uint64_t
*
ended_at
=
NULL
);
uint64_t
split
(
const
char
*
newdesc
=
NULL
)
{
uint64_t
rtn
=
end
();
restart
(
newdesc
);
return
rtn
;
}
uint64_t
getStartTime
()
const
{
return
start_time
;
}
};
bool
startswith
(
const
std
::
string
&
s
,
const
std
::
string
&
pattern
);
...
...
src/gc/collector.cpp
View file @
600208d0
...
...
@@ -339,13 +339,13 @@ void runCollection() {
static
StatCounter
sc
(
"gc_collections"
);
sc
.
log
();
STAT_TIMER
(
t0
,
"us_timer_gc_collection"
);
ncollections
++
;
if
(
VERBOSITY
(
"gc"
)
>=
2
)
printf
(
"Collection #%d
\n
"
,
ncollections
);
Timer
_t
(
"collecting"
,
/*min_usec=*/
10000
);
markPhase
();
std
::
list
<
Box
*
,
StlCompatAllocator
<
Box
*>>
weakly_referenced
;
sweepPhase
(
weakly_referenced
);
...
...
@@ -369,10 +369,6 @@ void runCollection() {
if
(
VERBOSITY
(
"gc"
)
>=
2
)
printf
(
"Collection #%d done
\n\n
"
,
ncollections
);
long
us
=
_t
.
end
();
static
StatCounter
sc_us
(
"gc_collections_us"
);
sc_us
.
log
(
us
);
// dumpHeapStatistics();
}
...
...
src/gc/gc_alloc.h
View file @
600208d0
...
...
@@ -28,7 +28,9 @@ namespace pyston {
namespace
gc
{
static
StatCounter
gc_alloc_bytes
(
"zzz_gc_alloc_bytes"
);
extern
"C"
inline
void
*
gc_alloc
(
size_t
bytes
,
GCKind
kind_id
)
{
STAT_TIMER
(
t0
,
"us_timer_gc_alloc"
);
size_t
alloc_bytes
=
bytes
+
sizeof
(
GCAllocation
);
#ifndef NVALGRIND
...
...
@@ -89,8 +91,10 @@ extern "C" inline void* gc_alloc(size_t bytes, GCKind kind_id) {
// if (VERBOSITY()) printf("Allocated %ld bytes at [%p, %p)\n", bytes, r, (char*)r + bytes);
#endif
// printf("Allocated %p\n", r);
#if STAT_ALLOCATIONS
gc_alloc_bytes
.
log
(
bytes
);
#endif
return
r
;
}
...
...
@@ -128,6 +132,10 @@ extern "C" inline void* gc_realloc(void* ptr, size_t bytes) {
alloc
->
kind_data
=
bytes
;
}
#if STAT_ALLOCATIONS
gc_alloc_bytes
.
log
(
bytes
);
#endif
return
rtn
;
}
...
...
src/jit.cpp
View file @
600208d0
This diff is collapsed.
Click to expand it.
src/runtime/builtin_modules/builtins.cpp
View file @
600208d0
...
...
@@ -303,6 +303,7 @@ extern "C" Box* ord(Box* obj) {
}
Box
*
range
(
Box
*
start
,
Box
*
stop
,
Box
*
step
)
{
STAT_TIMER
(
t0
,
"us_timer_builtin_range"
);
i64
istart
,
istop
,
istep
;
if
(
stop
==
NULL
)
{
istart
=
0
;
...
...
@@ -346,6 +347,7 @@ Box* notimplementedRepr(Box* self) {
}
Box
*
sorted
(
Box
*
obj
,
Box
*
cmp
,
Box
*
key
,
Box
**
args
)
{
STAT_TIMER
(
t0
,
"us_timer_builtin_sorted"
);
Box
*
reverse
=
args
[
0
];
BoxedList
*
rtn
=
new
BoxedList
();
...
...
@@ -358,6 +360,7 @@ Box* sorted(Box* obj, Box* cmp, Box* key, Box** args) {
}
Box
*
isinstance_func
(
Box
*
obj
,
Box
*
cls
)
{
STAT_TIMER
(
t0
,
"us_timer_builtin_isinstance"
);
int
rtn
=
PyObject_IsInstance
(
obj
,
cls
);
if
(
rtn
<
0
)
checkAndThrowCAPIException
();
...
...
@@ -365,6 +368,7 @@ Box* isinstance_func(Box* obj, Box* cls) {
}
Box
*
issubclass_func
(
Box
*
child
,
Box
*
parent
)
{
STAT_TIMER
(
t0
,
"us_timer_builtin_issubclass"
);
int
rtn
=
PyObject_IsSubclass
(
child
,
parent
);
if
(
rtn
<
0
)
checkAndThrowCAPIException
();
...
...
src/runtime/dict.cpp
View file @
600208d0
...
...
@@ -48,6 +48,7 @@ Box* dictRepr(BoxedDict* self) {
}
Box
*
dictClear
(
BoxedDict
*
self
)
{
STAT_TIMER
(
t0
,
"us_timer_dictClear"
);
if
(
!
isSubclass
(
self
->
cls
,
dict_cls
))
raiseExcHelper
(
TypeError
,
"descriptor 'clear' requires a 'dict' object but received a '%s'"
,
getTypeName
(
self
));
...
...
@@ -56,6 +57,7 @@ Box* dictClear(BoxedDict* self) {
}
Box
*
dictCopy
(
BoxedDict
*
self
)
{
STAT_TIMER
(
t0
,
"us_timer_dictCopy"
);
if
(
!
isSubclass
(
self
->
cls
,
dict_cls
))
raiseExcHelper
(
TypeError
,
"descriptor 'copy' requires a 'dict' object but received a '%s'"
,
getTypeName
(
self
));
...
...
@@ -65,6 +67,7 @@ Box* dictCopy(BoxedDict* self) {
}
Box
*
dictItems
(
BoxedDict
*
self
)
{
STAT_TIMER
(
t0
,
"us_timer_dictItems"
);
BoxedList
*
rtn
=
new
BoxedList
();
rtn
->
ensure
(
self
->
d
.
size
());
...
...
@@ -77,6 +80,7 @@ Box* dictItems(BoxedDict* self) {
}
Box
*
dictValues
(
BoxedDict
*
self
)
{
STAT_TIMER
(
t0
,
"us_timer_dictValues"
);
BoxedList
*
rtn
=
new
BoxedList
();
rtn
->
ensure
(
self
->
d
.
size
());
for
(
const
auto
&
p
:
self
->
d
)
{
...
...
@@ -86,6 +90,7 @@ Box* dictValues(BoxedDict* self) {
}
Box
*
dictKeys
(
BoxedDict
*
self
)
{
STAT_TIMER
(
t0
,
"us_timer_dictKeys"
);
RELEASE_ASSERT
(
isSubclass
(
self
->
cls
,
dict_cls
),
""
);
BoxedList
*
rtn
=
new
BoxedList
();
...
...
@@ -182,6 +187,7 @@ extern "C" int PyDict_Update(PyObject* a, PyObject* b) noexcept {
}
Box
*
dictGetitem
(
BoxedDict
*
self
,
Box
*
k
)
{
STAT_TIMER
(
t0
,
"us_timer_dictGetitem"
);
if
(
!
isSubclass
(
self
->
cls
,
dict_cls
))
raiseExcHelper
(
TypeError
,
"descriptor '__getitem__' requires a 'dict' object but received a '%s'"
,
getTypeName
(
self
));
...
...
@@ -306,6 +312,7 @@ extern "C" PyObject* PyDict_GetItemString(PyObject* dict, const char* key) noexc
}
Box
*
dictSetitem
(
BoxedDict
*
self
,
Box
*
k
,
Box
*
v
)
{
STAT_TIMER
(
t0
,
"us_timer_dictSetitem"
);
// printf("Starting setitem\n");
Box
*&
pos
=
self
->
d
[
k
];
// printf("Got the pos\n");
...
...
@@ -320,6 +327,7 @@ Box* dictSetitem(BoxedDict* self, Box* k, Box* v) {
}
Box
*
dictDelitem
(
BoxedDict
*
self
,
Box
*
k
)
{
STAT_TIMER
(
t0
,
"us_timer_dictDelitem"
);
if
(
!
isSubclass
(
self
->
cls
,
dict_cls
))
raiseExcHelper
(
TypeError
,
"descriptor '__delitem__' requires a 'dict' object but received a '%s'"
,
getTypeName
(
self
));
...
...
src/runtime/generator.cpp
View file @
600208d0
...
...
@@ -86,28 +86,36 @@ Context* getReturnContextForGeneratorFrame(void* frame_addr) {
}
void
generatorEntry
(
BoxedGenerator
*
g
)
{
assert
(
g
->
cls
==
generator_cls
);
assert
(
g
->
function
->
cls
==
function_cls
);
{
STAT_TIMER2
(
t0
,
"us_timer_generator_toplevel"
,
g
->
timer_time
);
threading
::
pushGenerator
(
g
,
g
->
stack_begin
,
g
->
returnContext
);
assert
(
g
->
cls
==
generator_cls
);
assert
(
g
->
function
->
cls
==
function_cls
);
try
{
RegisterHelper
context_registerer
(
g
,
__builtin_frame_address
(
0
));
threading
::
pushGenerator
(
g
,
g
->
stack_begin
,
g
->
returnContext
);
try
{
RegisterHelper
context_registerer
(
g
,
__builtin_frame_address
(
0
));
// call body of the generator
BoxedFunctionBase
*
func
=
g
->
function
;
// call body of the generator
BoxedFunctionBase
*
func
=
g
->
function
;
Box
**
args
=
g
->
args
?
&
g
->
args
->
elts
[
0
]
:
nullptr
;
callCLFunc
(
func
->
f
,
nullptr
,
func
->
f
->
numReceivedArgs
(),
func
->
closure
,
g
,
func
->
globals
,
g
->
arg1
,
g
->
arg2
,
g
->
arg3
,
args
);
}
catch
(
ExcInfo
e
)
{
// unhandled exception: propagate the exception to the caller
g
->
exception
=
e
;
}
Box
**
args
=
g
->
args
?
&
g
->
args
->
elts
[
0
]
:
nullptr
;
callCLFunc
(
func
->
f
,
nullptr
,
func
->
f
->
numReceivedArgs
(),
func
->
closure
,
g
,
func
->
globals
,
g
->
arg1
,
g
->
arg2
,
g
->
arg3
,
args
);
}
catch
(
ExcInfo
e
)
{
// unhandled exception: propagate the exception to the caller
g
->
exception
=
e
;
}
// we returned from the body of the generator. next/send/throw will notify the caller
g
->
entryExited
=
true
;
threading
::
popGenerator
();
// we returned from the body of the generator. next/send/throw will notify the caller
g
->
entryExited
=
true
;
threading
::
popGenerator
();
#if !DISABLE_STATS
g
->
timer_time
=
getCPUTicks
();
// store off the timer that our caller (in g->returnContext) will resume at
STAT_TIMER_NAME
(
t0
).
pause
(
g
->
timer_time
);
#endif
}
swapContext
(
&
g
->
context
,
g
->
returnContext
,
0
);
}
...
...
@@ -130,7 +138,21 @@ Box* generatorSend(Box* s, Box* v) {
self
->
returnValue
=
v
;
self
->
running
=
true
;
#if !DISABLE_STATS
// store off the time that the generator will use to initialize its toplevel timer
self
->
timer_time
=
getCPUTicks
();
StatTimer
*
current_timers
=
StatTimer
::
swapStack
(
self
->
statTimers
,
self
->
timer_time
);
#endif
swapContext
(
&
self
->
returnContext
,
self
->
context
,
(
intptr_t
)
self
);
#if !DISABLE_STATS
// if the generator exited we use the time that generatorEntry stored in self->timer_time (the same time it paused
// its timer at).
self
->
statTimers
=
StatTimer
::
swapStack
(
current_timers
,
self
->
entryExited
?
self
->
timer_time
:
getCPUTicks
());
#endif
self
->
running
=
false
;
// propagate exception to the caller
...
...
src/runtime/list.cpp
View file @
600208d0
...
...
@@ -542,6 +542,8 @@ extern "C" Box* listInsert(BoxedList* self, Box* idx, Box* v) {
}
Box
*
listMul
(
BoxedList
*
self
,
Box
*
rhs
)
{
STAT_TIMER
(
t0
,
"us_timer_listMul"
);
if
(
rhs
->
cls
!=
int_cls
)
{
raiseExcHelper
(
TypeError
,
"can't multiply sequence by non-int of type '%s'"
,
getTypeName
(
rhs
));
}
...
...
src/runtime/objmodel.cpp
View file @
600208d0
This diff is collapsed.
Click to expand it.
src/runtime/stacktrace.cpp
View file @
600208d0
...
...
@@ -96,6 +96,7 @@ void unwindExc(Box* exc_obj) {
void
raiseRaw
(
const
ExcInfo
&
e
)
__attribute__
((
__noreturn__
));
void
raiseRaw
(
const
ExcInfo
&
e
)
{
STAT_TIMER
(
t0
,
"us_timer_raiseraw"
);
// Should set these to None before getting here:
assert
(
e
.
type
);
assert
(
e
.
value
);
...
...
src/runtime/str.cpp
View file @
600208d0
...
...
@@ -1112,6 +1112,7 @@ extern "C" Box* strMod(BoxedString* lhs, Box* rhs) {
}
extern
"C"
Box
*
strMul
(
BoxedString
*
lhs
,
Box
*
rhs
)
{
STAT_TIMER
(
t0
,
"us_timer_strMul"
);
assert
(
isSubclass
(
lhs
->
cls
,
str_cls
));
int
n
;
...
...
@@ -1514,6 +1515,7 @@ failed:
}
extern
"C"
size_t
unicodeHashUnboxed
(
PyUnicodeObject
*
self
)
{
STAT_TIMER
(
t0
,
"us_timer_unicodeHashUnboxed"
);
if
(
self
->
hash
!=
-
1
)
return
self
->
hash
;
...
...
@@ -1524,6 +1526,7 @@ extern "C" size_t unicodeHashUnboxed(PyUnicodeObject* self) {
}
extern
"C"
Box
*
strHash
(
BoxedString
*
self
)
{
STAT_TIMER
(
t0
,
"us_timer_strHash"
);
assert
(
isSubclass
(
self
->
cls
,
str_cls
));
StringHash
<
char
>
H
;
...
...
src/runtime/tuple.cpp
View file @
600208d0
...
...
@@ -168,6 +168,7 @@ Box* tupleAdd(BoxedTuple* self, Box* rhs) {
}
Box
*
tupleMul
(
BoxedTuple
*
self
,
Box
*
rhs
)
{
STAT_TIMER
(
t0
,
"us_timer_tupleMul"
);
if
(
rhs
->
cls
!=
int_cls
)
{
raiseExcHelper
(
TypeError
,
"can't multiply sequence by non-int of type '%s'"
,
getTypeName
(
rhs
));
}
...
...
@@ -337,6 +338,7 @@ Box* tupleIndex(BoxedTuple* self, Box* elt) {
}
Box
*
tupleHash
(
BoxedTuple
*
self
)
{
STAT_TIMER
(
t0
,
"us_timer_tupleHash"
);
assert
(
isSubclass
(
self
->
cls
,
tuple_cls
));
int64_t
rtn
=
3527539
;
...
...
src/runtime/types.cpp
View file @
600208d0
...
...
@@ -1238,6 +1238,8 @@ public:
}
static
Box
*
setitem
(
Box
*
_self
,
Box
*
_key
,
Box
*
value
)
{
STAT_TIMER
(
t0
,
"us_timer_AttrWrapper_setitem"
);
RELEASE_ASSERT
(
_self
->
cls
==
attrwrapper_cls
,
""
);
AttrWrapper
*
self
=
static_cast
<
AttrWrapper
*>
(
_self
);
...
...
@@ -1250,6 +1252,7 @@ public:
}
static
Box
*
setdefault
(
Box
*
_self
,
Box
*
_key
,
Box
*
value
)
{
STAT_TIMER
(
t0
,
"us_timer_AttrWrapper_setdefault"
);
RELEASE_ASSERT
(
_self
->
cls
==
attrwrapper_cls
,
""
);
AttrWrapper
*
self
=
static_cast
<
AttrWrapper
*>
(
_self
);
...
...
@@ -1265,6 +1268,7 @@ public:
}
static
Box
*
get
(
Box
*
_self
,
Box
*
_key
,
Box
*
def
)
{
STAT_TIMER
(
t0
,
"us_timer_AttrWrapper_get"
);
RELEASE_ASSERT
(
_self
->
cls
==
attrwrapper_cls
,
""
);
AttrWrapper
*
self
=
static_cast
<
AttrWrapper
*>
(
_self
);
...
...
@@ -1279,6 +1283,7 @@ public:
}
static
Box
*
getitem
(
Box
*
_self
,
Box
*
_key
)
{
STAT_TIMER
(
t0
,
"us_timer_AttrWrapper_getitem"
);
RELEASE_ASSERT
(
_self
->
cls
==
attrwrapper_cls
,
""
);
AttrWrapper
*
self
=
static_cast
<
AttrWrapper
*>
(
_self
);
...
...
@@ -1312,6 +1317,7 @@ public:
}
static
Box
*
delitem
(
Box
*
_self
,
Box
*
_key
)
{
STAT_TIMER
(
t0
,
"us_timer_AttrWrapper_delitem"
);
RELEASE_ASSERT
(
_self
->
cls
==
attrwrapper_cls
,
""
);
AttrWrapper
*
self
=
static_cast
<
AttrWrapper
*>
(
_self
);
...
...
@@ -1377,6 +1383,7 @@ public:
}
static
Box
*
values
(
Box
*
_self
)
{
STAT_TIMER
(
t0
,
"us_timer_AttrWrapper_values"
);
RELEASE_ASSERT
(
_self
->
cls
==
attrwrapper_cls
,
""
);
AttrWrapper
*
self
=
static_cast
<
AttrWrapper
*>
(
_self
);
...
...
@@ -1391,6 +1398,7 @@ public:
}
static
Box
*
items
(
Box
*
_self
)
{
STAT_TIMER
(
t0
,
"us_timer_AttrWrapper_items"
);
RELEASE_ASSERT
(
_self
->
cls
==
attrwrapper_cls
,
""
);
AttrWrapper
*
self
=
static_cast
<
AttrWrapper
*>
(
_self
);
...
...
@@ -1429,6 +1437,7 @@ public:
}
static
Box
*
update
(
Box
*
_self
,
Box
*
_container
)
{
STAT_TIMER
(
t0
,
"us_timer_AttrWrapper_update"
);
RELEASE_ASSERT
(
_self
->
cls
==
attrwrapper_cls
,
""
);
AttrWrapper
*
self
=
static_cast
<
AttrWrapper
*>
(
_self
);
...
...
src/runtime/types.h
View file @
600208d0
...
...
@@ -410,12 +410,37 @@ public:
size_t
size
()
{
return
s
.
size
();
}
void
*
operator
new
(
size_t
size
,
size_t
ssize
)
__attribute__
((
visibility
(
"default"
)))
{
#if STAT_ALLOCATIONS
static
StatCounter
alloc_str
(
"alloc.str"
);
static
StatCounter
alloc_str1
(
"alloc.str(1)"
);
static
StatCounter
allocsize_str
(
"allocsize.str"
);
if
(
ssize
==
1
)
alloc_str1
.
log
();
else
alloc_str
.
log
();
allocsize_str
.
log
(
str_cls
->
tp_basicsize
+
ssize
+
1
);
#endif
Box
*
rtn
=
static_cast
<
Box
*>
(
gc_alloc
(
str_cls
->
tp_basicsize
+
ssize
+
1
,
gc
::
GCKind
::
PYTHON
));
rtn
->
cls
=
str_cls
;
return
rtn
;
}
void
*
operator
new
(
size_t
size
,
BoxedClass
*
cls
,
size_t
ssize
)
__attribute__
((
visibility
(
"default"
)))
{
#if STAT_ALLOCATIONS
static
StatCounter
alloc_str
(
"alloc.str"
);
static
StatCounter
alloc_str1
(
"alloc.str(1)"
);
static
StatCounter
allocsize_str
(
"allocsize.str"
);
if
(
ssize
==
1
)
alloc_str1
.
log
();
else
alloc_str
.
log
();
allocsize_str
.
log
(
cls
->
tp_basicsize
+
ssize
+
1
);
#endif
Box
*
rtn
=
static_cast
<
Box
*>
(
cls
->
tp_alloc
(
cls
,
ssize
+
1
));
rtn
->
cls
=
cls
;
return
rtn
;
...
...
@@ -517,12 +542,43 @@ public:
Box
**
elts
;
void
*
operator
new
(
size_t
size
,
size_t
nelts
)
__attribute__
((
visibility
(
"default"
)))
{
#if STAT_ALLOCATIONS
static
StatCounter
alloc_tuple
(
"alloc.tuple"
);
static
StatCounter
alloc_tuple0
(
"alloc.tuple(0)"
);
static
StatCounter
allocsize_tuple
(
"allocsize.tuple"
);
static
StatCounter
allocsize_tuple0
(
"allocsize.tuple(0)"
);
if
(
nelts
==
0
)
{
alloc_tuple0
.
log
();
allocsize_tuple0
.
log
(
_PyObject_VAR_SIZE
(
tuple_cls
,
nelts
+
1
));
}
else
{
alloc_tuple
.
log
();
allocsize_tuple
.
log
(
_PyObject_VAR_SIZE
(
tuple_cls
,
nelts
+
1
));
}
#endif
Box
*
rtn
=
static_cast
<
Box
*>
(
gc_alloc
(
_PyObject_VAR_SIZE
(
tuple_cls
,
nelts
+
1
),
gc
::
GCKind
::
PYTHON
));
rtn
->
cls
=
tuple_cls
;
return
rtn
;
}
void
*
operator
new
(
size_t
size
,
BoxedClass
*
cls
,
size_t
nelts
)
__attribute__
((
visibility
(
"default"
)))
{
#if STAT_ALLOCATIONS
static
StatCounter
alloc_tuple
(
"alloc.tuple"
);
static
StatCounter
alloc_tuple0
(
"alloc.tuple(0)"
);
static
StatCounter
allocsize_tuple
(
"allocsize.tuple"
);
static
StatCounter
allocsize_tuple0
(
"allocsize.tuple(0)"
);
if
(
nelts
==
0
)
{
alloc_tuple0
.
log
();
allocsize_tuple0
.
log
(
_PyObject_VAR_SIZE
(
cls
,
nelts
+
1
));
}
else
{
alloc_tuple
.
log
();
allocsize_tuple
.
log
(
_PyObject_VAR_SIZE
(
cls
,
nelts
+
1
));
}
#endif
Box
*
rtn
=
static_cast
<
Box
*>
(
cls
->
tp_alloc
(
cls
,
nelts
));
rtn
->
cls
=
cls
;
return
rtn
;
...
...
@@ -817,6 +873,11 @@ public:
struct
Context
*
context
,
*
returnContext
;
void
*
stack_begin
;
#if !DISABLE_STATS
StatTimer
*
statTimers
;
uint64_t
timer_time
;
#endif
BoxedGenerator
(
BoxedFunctionBase
*
function
,
Box
*
arg1
,
Box
*
arg2
,
Box
*
arg3
,
Box
**
args
);
DEFAULT_CLASS
(
generator_cls
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment