[pypy-commit] pypy gc-hooks: add a count stat which counts how many events have been fired since the last time the hook was called; also, make duration cumulative, so that we can know the total time spent in each event since the last hook was called
antocuni
pypy.commits at gmail.com
Tue Apr 10 04:47:32 EDT 2018
Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: gc-hooks
Changeset: r94302:ada614ebe930
Date: 2018-04-10 10:43 +0200
http://bitbucket.org/pypy/pypy/changeset/ada614ebe930/
Log: add a count stat which counts how many events have been fired since
the last time the hook was called; also, make duration cumulative,
so that we can know the total time spent in each event since the
last hook was called
diff --git a/pypy/module/gc/hook.py b/pypy/module/gc/hook.py
--- a/pypy/module/gc/hook.py
+++ b/pypy/module/gc/hook.py
@@ -33,14 +33,16 @@
def on_gc_minor(self, duration, total_memory_used, pinned_objects):
action = self.w_hooks.gc_minor
- action.duration = duration
+ action.count += 1
+ action.duration += duration
action.total_memory_used = total_memory_used
action.pinned_objects = pinned_objects
action.fire()
def on_gc_collect_step(self, duration, oldstate, newstate):
action = self.w_hooks.gc_collect_step
- action.duration = duration
+ action.count += 1
+ action.duration += duration
action.oldstate = oldstate
action.newstate = newstate
action.fire()
@@ -50,6 +52,7 @@
arenas_bytes, rawmalloc_bytes_before,
rawmalloc_bytes_after):
action = self.w_hooks.gc_collect
+ action.count += 1
action.num_major_collects = num_major_collects
action.arenas_count_before = arenas_count_before
action.arenas_count_after = arenas_count_after
@@ -109,6 +112,7 @@
class GcMinorHookAction(AsyncAction):
+ count = 0
duration = 0
total_memory_used = 0
pinned_objects = 0
@@ -117,11 +121,16 @@
AsyncAction.__init__(self, space)
self.w_callable = space.w_None
+ def reset(self):
+ self.count = 0
+ self.duration = 0
+
def fix_annotation(self):
# the annotation of the class and its attributes must be completed
# BEFORE we do the gc transform; this makes sure that everything is
# annotated with the correct types
if NonConstant(False):
+ self.count = NonConstant(-42)
self.duration = NonConstant(-42)
self.total_memory_used = NonConstant(r_uint(42))
self.pinned_objects = NonConstant(-42)
@@ -129,13 +138,16 @@
def perform(self, ec, frame):
w_stats = W_GcMinorStats(
+ self.count,
self.duration,
self.total_memory_used,
self.pinned_objects)
+ self.reset()
self.space.call_function(self.w_callable, w_stats)
class GcCollectStepHookAction(AsyncAction):
+ count = 0
duration = 0
oldstate = 0
newstate = 0
@@ -144,11 +156,16 @@
AsyncAction.__init__(self, space)
self.w_callable = space.w_None
+ def reset(self):
+ self.count = 0
+ self.duration = 0
+
def fix_annotation(self):
# the annotation of the class and its attributes must be completed
# BEFORE we do the gc transform; this makes sure that everything is
# annotated with the correct types
if NonConstant(False):
+ self.count = NonConstant(-42)
self.duration = NonConstant(-42)
self.oldstate = NonConstant(-42)
self.newstate = NonConstant(-42)
@@ -156,13 +173,16 @@
def perform(self, ec, frame):
w_stats = W_GcCollectStepStats(
+ self.count,
self.duration,
self.oldstate,
self.newstate)
+ self.reset()
self.space.call_function(self.w_callable, w_stats)
class GcCollectHookAction(AsyncAction):
+ count = 0
num_major_collects = 0
arenas_count_before = 0
arenas_count_after = 0
@@ -174,11 +194,16 @@
AsyncAction.__init__(self, space)
self.w_callable = space.w_None
+ def reset(self):
+ self.count = 0
+ self.duration = 0
+
def fix_annotation(self):
# the annotation of the class and its attributes must be completed
# BEFORE we do the gc transform; this makes sure that everything is
# annotated with the correct types
if NonConstant(False):
+ self.count = NonConstant(-42)
self.num_major_collects = NonConstant(-42)
self.arenas_count_before = NonConstant(-42)
self.arenas_count_after = NonConstant(-42)
@@ -188,18 +213,21 @@
self.fire()
def perform(self, ec, frame):
- w_stats = W_GcCollectStats(self.num_major_collects,
+ w_stats = W_GcCollectStats(self.count,
+ self.num_major_collects,
self.arenas_count_before,
self.arenas_count_after,
self.arenas_bytes,
self.rawmalloc_bytes_before,
self.rawmalloc_bytes_after)
+ self.reset()
self.space.call_function(self.w_callable, w_stats)
class W_GcMinorStats(W_Root):
- def __init__(self, duration, total_memory_used, pinned_objects):
+ def __init__(self, count, duration, total_memory_used, pinned_objects):
+ self.count = count
self.duration = duration
self.total_memory_used = total_memory_used
self.pinned_objects = pinned_objects
@@ -207,17 +235,19 @@
class W_GcCollectStepStats(W_Root):
- def __init__(self, duration, oldstate, newstate):
+ def __init__(self, count, duration, oldstate, newstate):
+ self.count = count
self.duration = duration
self.oldstate = oldstate
self.newstate = newstate
class W_GcCollectStats(W_Root):
- def __init__(self, num_major_collects,
+ def __init__(self, count, num_major_collects,
arenas_count_before, arenas_count_after,
arenas_bytes, rawmalloc_bytes_before,
rawmalloc_bytes_after):
+ self.count = count
self.num_major_collects = num_major_collects
self.arenas_count_before = arenas_count_before
self.arenas_count_after = arenas_count_after
@@ -255,6 +285,7 @@
W_GcMinorStats.typedef = TypeDef(
"GcMinorStats",
**wrap_many_ints(W_GcMinorStats, (
+ "count",
"duration",
"total_memory_used",
"pinned_objects"))
@@ -268,6 +299,7 @@
STATE_FINALIZING = incminimark.STATE_FINALIZING,
GC_STATES = tuple(incminimark.GC_STATES),
**wrap_many_ints(W_GcCollectStepStats, (
+ "count",
"duration",
"oldstate",
"newstate"))
@@ -276,6 +308,7 @@
W_GcCollectStats.typedef = TypeDef(
"GcCollectStats",
**wrap_many_ints(W_GcCollectStats, (
+ "count",
"num_major_collects",
"arenas_count_before",
"arenas_count_after",
diff --git a/pypy/module/gc/test/test_hook.py b/pypy/module/gc/test/test_hook.py
--- a/pypy/module/gc/test/test_hook.py
+++ b/pypy/module/gc/test/test_hook.py
@@ -26,8 +26,11 @@
@unwrap_spec(ObjSpace)
def fire_many(space):
- gchooks.fire_gc_minor(0, 0, 0)
- gchooks.fire_gc_collect_step(0, 0, 0)
+ gchooks.fire_gc_minor(5, 0, 0)
+ gchooks.fire_gc_minor(7, 0, 0)
+ gchooks.fire_gc_collect_step(5, 0, 0)
+ gchooks.fire_gc_collect_step(15, 0, 0)
+ gchooks.fire_gc_collect_step(22, 0, 0)
gchooks.fire_gc_collect(1, 2, 3, 4, 5, 6)
cls.w_fire_gc_minor = space.wrap(interp2app(fire_gc_minor))
@@ -45,49 +48,54 @@
import gc
lst = []
def on_gc_minor(stats):
- tup = (stats.duration, stats.total_memory_used, stats.pinned_objects)
- lst.append(tup)
+ lst.append((stats.count,
+ stats.duration,
+ stats.total_memory_used,
+ stats.pinned_objects))
gc.hooks.on_gc_minor = on_gc_minor
self.fire_gc_minor(10, 20, 30)
self.fire_gc_minor(40, 50, 60)
assert lst == [
- (10, 20, 30),
- (40, 50, 60),
+ (1, 10, 20, 30),
+ (1, 40, 50, 60),
]
#
gc.hooks.on_gc_minor = None
self.fire_gc_minor(70, 80, 90) # won't fire because the hooks is disabled
assert lst == [
- (10, 20, 30),
- (40, 50, 60),
+ (1, 10, 20, 30),
+ (1, 40, 50, 60),
]
def test_on_gc_collect_step(self):
import gc
lst = []
def on_gc_collect_step(stats):
- tup = (stats.duration, stats.oldstate, stats.newstate)
- lst.append(tup)
+ lst.append((stats.count,
+ stats.duration,
+ stats.oldstate,
+ stats.newstate))
gc.hooks.on_gc_collect_step = on_gc_collect_step
self.fire_gc_collect_step(10, 20, 30)
self.fire_gc_collect_step(40, 50, 60)
assert lst == [
- (10, 20, 30),
- (40, 50, 60),
+ (1, 10, 20, 30),
+ (1, 40, 50, 60),
]
#
gc.hooks.on_gc_collect_step = None
self.fire_gc_collect_step(70, 80, 90) # won't fire
assert lst == [
- (10, 20, 30),
- (40, 50, 60),
+ (1, 10, 20, 30),
+ (1, 40, 50, 60),
]
def test_on_gc_collect(self):
import gc
lst = []
def on_gc_collect(stats):
- lst.append((stats.num_major_collects,
+ lst.append((stats.count,
+ stats.num_major_collects,
stats.arenas_count_before,
stats.arenas_count_after,
stats.arenas_bytes,
@@ -97,15 +105,15 @@
self.fire_gc_collect(1, 2, 3, 4, 5, 6)
self.fire_gc_collect(7, 8, 9, 10, 11, 12)
assert lst == [
- (1, 2, 3, 4, 5, 6),
- (7, 8, 9, 10, 11, 12),
+ (1, 1, 2, 3, 4, 5, 6),
+ (1, 7, 8, 9, 10, 11, 12),
]
#
gc.hooks.on_gc_collect = None
self.fire_gc_collect(42, 42, 42, 42, 42, 42) # won't fire
assert lst == [
- (1, 2, 3, 4, 5, 6),
- (7, 8, 9, 10, 11, 12),
+ (1, 1, 2, 3, 4, 5, 6),
+ (1, 7, 8, 9, 10, 11, 12),
]
def test_consts(self):
@@ -117,6 +125,28 @@
assert S.STATE_FINALIZING == 3
assert S.GC_STATES == ('SCANNING', 'MARKING', 'SWEEPING', 'FINALIZING')
+ def test_cumulative(self):
+ import gc
+ class MyHooks(object):
+
+ def __init__(self):
+ self.minors = []
+ self.steps = []
+
+ def on_gc_minor(self, stats):
+ self.minors.append((stats.count, stats.duration))
+
+ def on_gc_collect_step(self, stats):
+ self.steps.append((stats.count, stats.duration))
+
+ on_gc_collect = None
+
+ myhooks = MyHooks()
+ gc.hooks.set(myhooks)
+ self.fire_many()
+ assert myhooks.minors == [(2, 12)]
+ assert myhooks.steps == [(3, 42)]
+
def test_clear_queue(self):
import gc
class MyHooks(object):
More information about the pypy-commit
mailing list