[pypy-commit] pypy stmgc-c8-hashtable: hg merge c8ea66315864 (I made the branch slightly too early)

arigo noreply at buildbot.pypy.org
Thu Mar 12 18:02:50 CET 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: stmgc-c8-hashtable
Changeset: r76358:090025f6da69
Date: 2015-03-12 18:02 +0100
http://bitbucket.org/pypy/pypy/changeset/090025f6da69/

Log:	hg merge c8ea66315864 (I made the branch slightly too early)

diff --git a/pypy/stm/print_stm_log.py b/pypy/stm/print_stm_log.py
--- a/pypy/stm/print_stm_log.py
+++ b/pypy/stm/print_stm_log.py
@@ -91,7 +91,10 @@
         self.cpu_time_committed = 0.0
         self.cpu_time_aborted = 0.0
         self.cpu_time_paused = 0.0
+        self.cpu_time_gc_minor = 0.0
+        self.cpu_time_gc_major = 0.0
         self._prev = (0.0, "stop")
+        self._in_major_coll = None
         self.reset_counters()
 
     def reset_counters(self):
@@ -99,6 +102,7 @@
         self._transaction_pause_time = 0.0
         self._transaction_aborting = False
         self._transaction_inev = None
+        self._in_minor_coll = None
 
     def transaction_start(self, entry):
         self.reset_counters()
@@ -167,9 +171,29 @@
 
     def wait_for_other_inev(self, wait_time, out_conflicts):
         c = self.get_conflict(self._transaction_inev[0], out_conflicts)
-        assert wait_time >= 0
+        assert wait_time >= 0.0
         c.paused_time += wait_time
 
+    def gc_minor_start(self, event):
+        self._in_minor_coll = event.timestamp
+
+    def gc_minor_done(self, event):
+        if self._in_minor_coll is not None:
+            gc_time = event.timestamp - self._in_minor_coll
+            assert gc_time >= 0.0
+            self.cpu_time_gc_minor += gc_time
+            self._in_minor_coll = None
+
+    def gc_major_start(self, event):
+        self._in_major_coll = event.timestamp
+
+    def gc_major_done(self, event):
+        if self._in_major_coll is not None:
+            gc_time = event.timestamp - self._in_major_coll
+            assert gc_time >= 0.0
+            self.cpu_time_gc_major += gc_time
+            self._in_major_coll = None
+
 
 class ConflictSummary(object):
     def __init__(self, event, marker):
@@ -250,6 +274,14 @@
             t.transaction_pause(entry)
         elif entry.event == STM_WAIT_DONE:
             t.transaction_unpause(entry, conflicts)
+        elif entry.event == STM_GC_MINOR_START:
+            t.gc_minor_start(entry)
+        elif entry.event == STM_GC_MINOR_DONE:
+            t.gc_minor_done(entry)
+        elif entry.event == STM_GC_MAJOR_START:
+            t.gc_major_start(entry)
+        elif entry.event == STM_GC_MAJOR_DONE:
+            t.gc_major_done(entry)
     #
     if cnt == 0:
         raise Exception("empty file")
@@ -264,7 +296,7 @@
     start_time = stmlog.start_time
     total_time = stmlog.total_time
     print
-    print 'Total real time:       %.3fs' % (total_time,)
+    print 'Total real time:     %9.3fs' % (total_time,)
     #
     total_cpu_time_committed = stmlog.get_total_cpu_time_committed()
     total_cpu_time_aborted = stmlog.get_total_cpu_time_aborted()
@@ -272,14 +304,20 @@
     total_cpu_time_total = (total_cpu_time_committed +
                             total_cpu_time_aborted +
                             total_cpu_time_paused)
-    print 'CPU time in STM mode:  %.3fs (%s) committed' % (
+    total_cpu_time_gc_minor = stmlog.get_total_cpu_time_gc_minor()
+    total_cpu_time_gc_major = stmlog.get_total_cpu_time_gc_major()
+    print 'CPU time in STM mode:%9.3fs (%4s) committed' % (
         total_cpu_time_committed, percent(total_cpu_time_committed, total_time))
-    print '                       %.3fs (%s) aborted' % (
+    print '                     %9.3fs (%4s) aborted' % (
         total_cpu_time_aborted,   percent(total_cpu_time_aborted,   total_time))
-    print '                       %.3fs (%s) paused' % (
+    print '                     %9.3fs (%4s) paused' % (
         total_cpu_time_paused,    percent(total_cpu_time_paused,    total_time))
-    print '                       %.3fs (%s) total' % (
+    print '                     %9.3fs (%4s) TOTAL' % (
         total_cpu_time_total,     percent(total_cpu_time_total,     total_time))
+    print '           including %9.3fs (%4s) minor GC collections' % (
+        total_cpu_time_gc_minor,  percent(total_cpu_time_gc_minor,  total_time))
+    print '                 and %9.3fs (%4s) major GC collections' % (
+        total_cpu_time_gc_major,  percent(total_cpu_time_gc_major,  total_time))
     print
     #
     values = stmlog.get_conflicts()
@@ -308,6 +346,12 @@
     def get_total_cpu_time_paused(self):
         return sum([v.cpu_time_paused for v in self.threads.values()])
 
+    def get_total_cpu_time_gc_minor(self):
+        return sum([v.cpu_time_gc_minor for v in self.threads.values()])
+
+    def get_total_cpu_time_gc_major(self):
+        return sum([v.cpu_time_gc_major for v in self.threads.values()])
+
     def get_conflicts(self):
         values = self.conflicts.values()
         values.sort(key=ConflictSummary.sortkey)
diff --git a/rpython/translator/stm/test/test_inevitable.py b/rpython/translator/stm/test/test_inevitable.py
--- a/rpython/translator/stm/test/test_inevitable.py
+++ b/rpython/translator/stm/test/test_inevitable.py
@@ -6,7 +6,7 @@
 from rpython.translator.stm.inevitable import insert_turn_inevitable
 from rpython.translator.stm import inevitable
 from rpython.conftest import option
-
+import py
 
 CATEGORIES = [inevitable.ALWAYS_ALLOW_OPERATIONS,
               inevitable.CALLS,
@@ -38,8 +38,7 @@
 class LLSTMInevFrame(LLFrame):
     def op_stm_become_inevitable(self, info):
         assert info is not None
-        if self.llinterpreter.inevitable_cause is None:
-            self.llinterpreter.inevitable_cause = info
+        self.llinterpreter.inevitable_cause.append(info)
 
     def op_gc_dump_rpy_heap(self):
         pass    # for test_unsupported_op
@@ -65,7 +64,7 @@
         if option.view:
             self.translator.view()
         #
-        interp.inevitable_cause = None
+        interp.inevitable_cause = []
         result = interp.eval_graph(self.graph, args)
         return interp.inevitable_cause
 
@@ -79,7 +78,7 @@
             x1.foo = n
 
         res = self.interpret_inevitable(f1, [4])
-        assert res is None
+        assert res == []
 
     def test_unsupported_op(self):
         X = lltype.Struct('X', ('foo', lltype.Signed))
@@ -89,7 +88,7 @@
             llop.gc_dump_rpy_heap(lltype.Void)
 
         res = self.interpret_inevitable(f1, [])
-        assert res == 'gc_dump_rpy_heap'
+        assert res == ['gc_dump_rpy_heap']
 
     def test_raw_getfield(self):
         X = lltype.Struct('X', ('foo', lltype.Signed))
@@ -100,7 +99,7 @@
             return x1.foo
 
         res = self.interpret_inevitable(f1, [])
-        assert res == 'getfield'
+        assert res == ['getfield']
 
     def test_raw_getfield_immutable(self):
         X = lltype.Struct('X', ('foo', lltype.Signed),
@@ -112,7 +111,7 @@
             return x1.foo
 
         res = self.interpret_inevitable(f1, [])
-        assert res is None
+        assert res == []
 
     def test_raw_getfield_with_hint(self):
         X = lltype.Struct('X', ('foo', lltype.Signed),
@@ -124,7 +123,7 @@
             return x1.foo
 
         res = self.interpret_inevitable(f1, [])
-        assert res is None
+        assert res == []
 
     def test_raw_setfield(self):
         X = lltype.Struct('X', ('foo', lltype.Signed))
@@ -135,7 +134,7 @@
             x1.foo = n
 
         res = self.interpret_inevitable(f1, [43])
-        assert res == 'setfield'
+        assert res == ['setfield']
 
     def test_malloc_no_inevitable(self):
         X = lltype.GcStruct('X', ('foo', lltype.Signed))
@@ -144,7 +143,7 @@
             return lltype.malloc(X)
 
         res = self.interpret_inevitable(f1, [])
-        assert res is None
+        assert res == []
 
     def test_raw_malloc_1(self):
         X = lltype.Struct('X', ('foo', lltype.Signed))
@@ -154,7 +153,7 @@
             lltype.free(p, flavor='raw')
 
         res = self.interpret_inevitable(f1, [])
-        assert res is None
+        assert res == []
 
     def test_raw_malloc_2(self):
         X = lltype.Struct('X', ('foo', lltype.Signed))
@@ -164,7 +163,7 @@
             llmemory.raw_free(addr)
 
         res = self.interpret_inevitable(f1, [])
-        assert res is None
+        assert res == []
 
     def test_unknown_raw_free(self):
         X = lltype.Struct('X', ('foo', lltype.Signed))
@@ -172,7 +171,7 @@
             lltype.free(p, flavor='raw')
 
         res = self.interpret_inevitable(f2, [lltype.malloc(X, flavor='raw')])
-        assert res is None
+        assert res == []
 
 
     def test_ext_direct_call_safe(self):
@@ -185,7 +184,7 @@
             extfunc()
 
         res = self.interpret_inevitable(f1, [])
-        assert res is None
+        assert res == []
 
 
     def test_ext_direct_call_unsafe(self):
@@ -197,7 +196,7 @@
             extfunc()
 
         res = self.interpret_inevitable(f1, [])
-        assert res == 'extfunc()'
+        assert res == ['extfunc()']
 
     def test_rpy_direct_call(self):
         def f2():
@@ -206,7 +205,7 @@
             f2()
 
         res = self.interpret_inevitable(f1, [])
-        assert res is None
+        assert res == []
 
     def test_rpy_indirect_call(self):
         def f2():
@@ -221,7 +220,7 @@
             f()
 
         res = self.interpret_inevitable(f1, [True])
-        assert res is None
+        assert res == []
 
     def test_ext_indirect_call(self):
         TYPE = lltype.FuncType([], lltype.Void)
@@ -240,7 +239,7 @@
             f()
 
         res = self.interpret_inevitable(f1, [True])
-        assert res == 'indirect_call'
+        assert res == ['indirect_call']
 
     def test_instantiate_indirect_call(self):
         # inits are necessary to generate indirect_call
@@ -259,7 +258,7 @@
             c()
 
         res = self.interpret_inevitable(f1, [True])
-        assert res is None
+        assert res == []
 
     def test_raw_class_hint(self):
         class A:
@@ -278,7 +277,7 @@
             return i
 
         res = self.interpret_inevitable(f, [2])
-        assert res is None   # not setfield or getfield or free
+        assert res == []   # not setfield or getfield or free
 
     def test_do_malloc_llops(self):
         def f(i):
@@ -288,7 +287,7 @@
             return i
 
         res = self.interpret_inevitable(f, [2])
-        assert res is None
+        assert res == []
 
     def test_raw_load_nonpure(self):
         X = lltype.Struct('X', ('foo', lltype.Signed))
@@ -300,7 +299,7 @@
                 lltype.Signed, llmemory.cast_ptr_to_adr(x1), 0, False)
 
         res = self.interpret_inevitable(f1, [])
-        assert res == 'raw_load'
+        assert res == ['raw_load']
 
     def test_raw_load_pure(self):
         X = lltype.Struct('X', ('foo', lltype.Signed))
@@ -312,7 +311,7 @@
                 lltype.Signed, llmemory.cast_ptr_to_adr(x1), 0, True)
 
         res = self.interpret_inevitable(f1, [])
-        assert res is None
+        assert res == []
 
     def test_threadlocal(self):
         from rpython.rlib.rthread import ThreadLocalField
@@ -330,4 +329,84 @@
             #assert x == 42
 
         res = self.interpret_inevitable(f1, [])
-        assert res is None
+        assert res == []
+
+
+
+    def test_only_one_inev(self):
+        py.test.skip("not yet")
+        X = lltype.Struct('X', ('foo', lltype.Signed))
+        x1 = lltype.malloc(X, immortal=True)
+        x1.foo = 42
+
+        def f1():
+            r = 0
+            r += x1.foo
+            r += x1.foo
+            return r
+
+        res = self.interpret_inevitable(f1, [])
+        assert res == ['getfield']
+
+    def test_only_one_inev2(self):
+        py.test.skip("not yet")
+        X = lltype.Struct('X', ('foo', lltype.Signed))
+        x1 = lltype.malloc(X, immortal=True)
+        x1.foo = 42
+
+        def f1(i):
+            r = 0
+            if i:
+                r += x1.foo
+            r += x1.foo
+            return r
+
+        res = self.interpret_inevitable(f1, [1])
+        assert res == ['getfield']
+
+
+    def test_not_for_local_raw(self):
+        py.test.skip("not yet")
+        X = lltype.Struct('X', ('foo', lltype.Signed))
+
+        def f1(i):
+            x1 = lltype.malloc(X, flavor='raw')
+            x1.foo = 42
+            r = x1.foo
+            lltype.free(x1, flavor='raw')
+            return r
+
+        res = self.interpret_inevitable(f1, [1])
+        assert res == []
+
+
+    def test_for_unknown_raw(self):
+        py.test.skip("not yet")
+        X = lltype.Struct('X', ('foo', lltype.Signed))
+
+        def f1(i):
+            x1 = lltype.malloc(X, flavor='raw')
+            x1.foo = 42
+            r = x1.foo
+            if i:
+                lltype.free(x1, flavor='raw')
+            return r
+
+        res = self.interpret_inevitable(f1, [1])
+        assert res == ['setfield', 'getfield']
+
+
+    def test_local_raw_in_same_transaction(self):
+        py.test.skip("not yet")
+        X = lltype.Struct('X', ('foo', lltype.Signed))
+
+        def f1(i):
+            x1 = lltype.malloc(X, flavor='raw')
+            x1.foo = 42
+            r = x1.foo
+            func() # gil-release, non-gil-release, random-gc-effects????
+            lltype.free(x1, flavor='raw')
+            return r
+
+        res = self.interpret_inevitable(f1, [1])
+        assert res == []


More information about the pypy-commit mailing list