Author: Armin Rigo <[email protected]>
Branch: stmgc-c7
Changeset: r75427:dd8bd6ba13a9
Date: 2015-01-18 16:03 +0100
http://bitbucket.org/pypy/pypy/changeset/dd8bd6ba13a9/

Log:    Try harder to preserve the stm_location

diff --git a/TODO b/TODO
--- a/TODO
+++ b/TODO
@@ -143,6 +143,8 @@
 
 ------------------------------------------------------------
 
+stm_read(p125)
+cond_call_gc_wb_array(p125...)    # don't need the stm_read maybe?
 
 
 
diff --git a/rpython/jit/backend/llsupport/gc.py 
b/rpython/jit/backend/llsupport/gc.py
--- a/rpython/jit/backend/llsupport/gc.py
+++ b/rpython/jit/backend/llsupport/gc.py
@@ -145,8 +145,9 @@
         if op.is_guard() or op.getopnum() == rop.FINISH:
             # the only ops with descrs that get recorded in a trace
             llref = cast_instance_to_gcref(op.getdescr())
-            assert rgc._make_sure_does_not_move(llref)
-            gcrefs_output_list.append(llref)
+            if llref:
+                assert rgc._make_sure_does_not_move(llref)
+                gcrefs_output_list.append(llref)
         #
         if len(ops_with_movable_const_ptr[op]) == 0:
             del ops_with_movable_const_ptr[op]
diff --git a/rpython/jit/backend/llsupport/rewrite.py 
b/rpython/jit/backend/llsupport/rewrite.py
--- a/rpython/jit/backend/llsupport/rewrite.py
+++ b/rpython/jit/backend/llsupport/rewrite.py
@@ -38,6 +38,7 @@
     _previous_size = -1
     _op_malloc_nursery = None
     _v_last_malloced_nursery = None
+    stm_location = None
 
     # does_any_alloc tells us if we did any allocation since the last LABEL
     does_any_allocation = False
@@ -63,6 +64,8 @@
         #
         for i in range(len(operations)):
             op = operations[i]
+            if op.stm_location is not None:
+                self.stm_location = op.stm_location
             if op.getopnum() == rop.DEBUG_MERGE_POINT:
                 continue
             # ---------- turn NEWxxx into CALL_MALLOC_xxx ----------
@@ -110,6 +113,10 @@
         return self.newops
 
     def other_operation(self, op):
+        self.newop(op)
+
+    def newop(self, op):
+        op.stm_location = self.stm_location
         self.newops.append(op)
 
     def could_merge_with_next_guard(self, op, i, operations):
@@ -142,7 +149,7 @@
                 op = ResOperation(rop.SETFIELD_GC,
                                   [op.result, ConstInt(classint)], None,
                                   descr=self.gc_ll_descr.fielddescr_vtable)
-                self.newops.append(op)
+                self.newop(op)
         elif opnum == rop.NEW_ARRAY or opnum == rop.NEW_ARRAY_CLEAR:
             descr = op.getdescr()
             assert isinstance(descr, ArrayDescr)
@@ -202,7 +209,7 @@
             return
         op = ResOperation(rop.SETFIELD_GC, [result, self.c_zero], None,
                           descr=hash_descr)
-        self.newops.append(op)
+        self.newop(op)
 
     def handle_new_fixedsize(self, descr, op):
         assert isinstance(descr, SizeDescr)
@@ -264,7 +271,7 @@
         # See emit_pending_zeros().
         o = ResOperation(rop.ZERO_ARRAY, [v_arr, self.c_zero, v_length], None,
                          descr=arraydescr)
-        self.newops.append(o)
+        self.newop(o)
         if isinstance(v_length, ConstInt):
             self.last_zero_arrays.append(o)
 
@@ -276,7 +283,7 @@
             op0 = ResOperation(rop.GETFIELD_RAW, 
[history.ConstInt(frame_info)],
                                size_box,
                                descr=descrs.jfi_frame_depth)
-            self.newops.append(op0)
+            self.newop(op0)
             op1 = ResOperation(rop.NEW_ARRAY, [size_box], frame,
                                descr=descrs.arraydescr)
             self.handle_new_array(descrs.arraydescr, op1)
@@ -286,7 +293,7 @@
             op0 = ResOperation(rop.GETFIELD_RAW, 
[history.ConstInt(frame_info)],
                                size_box,
                                descr=descrs.jfi_frame_size)
-            self.newops.append(op0)
+            self.newop(op0)
             self.gen_malloc_nursery_varsize_frame(size_box, frame)
             self.gen_initialize_tid(frame, descrs.arraydescr.tid)
             length_box = history.BoxInt()
@@ -308,7 +315,8 @@
                 ResOperation(rop.SETFIELD_GC, [frame, self.c_null],
                              None, descr=descrs.jf_forward),
             ]
-            self.newops += extra_ops
+            for extra_op in extra_ops:
+                self.newop(extra_op)
             self.gen_initialize_len(frame, length_box,
                                     descrs.arraydescr.lendescr)
         else:
@@ -317,7 +325,7 @@
             op0 = ResOperation(rop.GETFIELD_RAW,[history.ConstInt(frame_info)],
                                length_box,
                                descr=descrs.jfi_frame_depth)
-            self.newops.append(op0)
+            self.newop(op0)
             self.gen_malloc_nursery_varsize_frame(length_box, frame)
             self.gen_initialize_tid(frame, descrs.arraydescr.tid)
             self.gen_initialize_len(frame, length_box,
@@ -333,7 +341,7 @@
         self.gen_malloc_frame(llfi, frame)
         op2 = ResOperation(rop.SETFIELD_GC, [frame, history.ConstInt(llfi)],
                            None, descr=descrs.jf_frame_info)
-        self.newops.append(op2)
+        self.newop(op2)
         arglist = op.getarglist()
         index_list = loop_token.compiled_loop_token._ll_initial_locs
         for i, arg in enumerate(arglist):
@@ -341,7 +349,7 @@
             assert self.cpu.JITFRAME_FIXED_SIZE & 1 == 0
             _, itemsize, _ = self.cpu.unpack_arraydescr_size(descr)
             index = index_list[i] // itemsize # index is in bytes
-            self.newops.append(ResOperation(rop.SETARRAYITEM_GC,
+            self.newop(ResOperation(rop.SETARRAYITEM_GC,
                                             [frame, ConstInt(index),
                                              arg],
                                             None, descr))
@@ -355,8 +363,7 @@
             args = [frame]
         op1 = ResOperation(rop.CALL_ASSEMBLER, args,
                            op.result, op.getdescr())
-        op1.stm_location = op.stm_location
-        self.newops.append(op1)
+        self.newop(op1)
 
     # ----------
 
@@ -399,14 +406,14 @@
         for v, d in self.delayed_zero_setfields.iteritems():
             for ofs in d.iterkeys():
                 op = ResOperation(rop.ZERO_PTR_FIELD, [v, ConstInt(ofs)], None)
-                self.newops.append(op)
+                self.newop(op)
         self.delayed_zero_setfields.clear()
 
     def _gen_call_malloc_gc(self, args, v_result, descr):
         """Generate a CALL_MALLOC_GC with the given args."""
         self.emitting_an_operation_that_can_collect()
         op = ResOperation(rop.CALL_MALLOC_GC, args, v_result, descr)
-        self.newops.append(op)
+        self.newop(op)
         # In general, don't add v_result to write_barrier_applied:
         # v_result might be a large young array.
 
@@ -493,7 +500,7 @@
         op = ResOperation(rop.CALL_MALLOC_NURSERY_VARSIZE,
                           [ConstInt(kind), ConstInt(itemsize), v_length],
                           v_result, descr=arraydescr)
-        self.newops.append(op)
+        self.newop(op)
         # don't record v_result into self.write_barrier_applied:
         # it can be a large, young array with card marking, and then
         # the GC relies on the write barrier being called
@@ -507,7 +514,7 @@
                           [sizebox],   # if STM, this is actually lengthbox!
                           v_result)
 
-        self.newops.append(op)
+        self.newop(op)
         self.write_barrier_applied[v_result] = None
 
     def gen_malloc_nursery(self, size, v_result):
@@ -539,7 +546,7 @@
                               v_result)
             self._op_malloc_nursery = op
         #
-        self.newops.append(op)
+        self.newop(op)
         self._previous_size = size
         self._v_last_malloced_nursery = v_result
         self.write_barrier_applied[v_result] = None
@@ -551,14 +558,14 @@
             op = ResOperation(rop.SETFIELD_GC,
                               [v_newgcobj, ConstInt(tid)], None,
                               descr=self.gc_ll_descr.fielddescr_tid)
-            self.newops.append(op)
+            self.newop(op)
 
     def gen_initialize_len(self, v_newgcobj, v_length, arraylen_descr):
         # produce a SETFIELD to initialize the array length
         op = ResOperation(rop.SETFIELD_GC,
                           [v_newgcobj, v_length], None,
                           descr=arraylen_descr)
-        self.newops.append(op)
+        self.newop(op)
 
     # ----------
 
@@ -572,27 +579,26 @@
     def handle_write_barrier_setfield(self, op):
         val = op.getarg(0)
         if self.must_apply_write_barrier(val, op.getarg(1)):
-            self.gen_write_barrier(val, op.stm_location)
-        self.newops.append(op)
+            self.gen_write_barrier(val)
+        self.newop(op)
 
     def handle_write_barrier_setarrayitem(self, op):
         val = op.getarg(0)
         if self.must_apply_write_barrier(val, op.getarg(2)):
-            self.gen_write_barrier_array(val, op.getarg(1), op.stm_location)
-        self.newops.append(op)
+            self.gen_write_barrier_array(val, op.getarg(1))
+        self.newop(op)
 
     handle_write_barrier_setinteriorfield = handle_write_barrier_setarrayitem
 
-    def gen_write_barrier(self, v_base, stm_location):
+    def gen_write_barrier(self, v_base):
         write_barrier_descr = self.gc_ll_descr.write_barrier_descr
         args = [v_base]
         op = ResOperation(rop.COND_CALL_GC_WB, args, None,
                           descr=write_barrier_descr)
-        op.stm_location = stm_location
-        self.newops.append(op)
+        self.newop(op)
         self.write_barrier_applied[v_base] = None
 
-    def gen_write_barrier_array(self, v_base, v_index, stm_location):
+    def gen_write_barrier_array(self, v_base, v_index):
         write_barrier_descr = self.gc_ll_descr.write_barrier_descr
         if write_barrier_descr.has_write_barrier_from_array(self.cpu):
             # If we know statically the length of 'v', and it is not too
@@ -605,13 +611,12 @@
                 args = [v_base, v_index]
                 op = ResOperation(rop.COND_CALL_GC_WB_ARRAY, args, None,
                                   descr=write_barrier_descr)
-                op.stm_location = stm_location
-                self.newops.append(op)
+                self.newop(op)
                 # a WB_ARRAY is not enough to prevent any future write
                 # barriers, so don't add to 'write_barrier_applied'!
                 return
         # fall-back case: produce a write_barrier
-        self.gen_write_barrier(v_base, stm_location)
+        self.gen_write_barrier(v_base)
 
     def round_up_for_allocation(self, size):
         if not self.gc_ll_descr.round_up:
diff --git a/rpython/jit/backend/llsupport/stmrewrite.py 
b/rpython/jit/backend/llsupport/stmrewrite.py
--- a/rpython/jit/backend/llsupport/stmrewrite.py
+++ b/rpython/jit/backend/llsupport/stmrewrite.py
@@ -20,22 +20,21 @@
     def other_operation(self, op):
         opnum = op.getopnum()
         if opnum == rop.INCREMENT_DEBUG_COUNTER:
-            self.newops.append(op)
+            self.newop(op)
             return
         # ----------  transaction breaks  ----------
         if opnum == rop.STM_HINT_COMMIT_SOON:
-            self._do_stm_call('stm_hint_commit_soon', [], None,
-                              op.stm_location)
+            self._do_stm_call('stm_hint_commit_soon', [], None)
             return
         # ----------  jump, finish, guard_not_forced_2  ----------
         if (opnum == rop.JUMP or opnum == rop.FINISH
                 or opnum == rop.GUARD_NOT_FORCED_2):
             self.add_dummy_allocation()
-            self.newops.append(op)
+            self.newop(op)
             return
         # ----------  pure operations, guards  ----------
         if op.is_always_pure() or op.is_guard() or op.is_ovf():
-            self.newops.append(op)
+            self.newop(op)
             return
         # ----------  non-pure getfields  ----------
         if opnum in (rop.GETFIELD_GC, rop.GETARRAYITEM_GC,
@@ -49,7 +48,7 @@
             if opnum == rop.CALL_RELEASE_GIL:
                 # self.fallback_inevitable(op)
                 # is done by assembler._release_gil_shadowstack()
-                self.newops.append(op)
+                self.newop(op)
             elif opnum == rop.CALL_ASSEMBLER:
                 assert 0   # case handled by the parent class
             else:
@@ -62,7 +61,7 @@
                       or descr.get_extra_info().call_needs_inevitable():
                     self.fallback_inevitable(op)
                 else:
-                    self.newops.append(op)
+                    self.newop(op)
             return
         # ----------  setters for pure fields  ----------
         if opnum in (rop.STRSETITEM, rop.UNICODESETITEM):
@@ -80,7 +79,7 @@
         if opnum == rop.LABEL:
             # note that the parent class also clears some things on a LABEL
             self.next_op_may_be_in_new_transaction()
-            self.newops.append(op)
+            self.newop(op)
             return
         # ----------  other ignored ops  ----------
         if opnum in (rop.STM_SHOULD_BREAK_TRANSACTION, rop.FORCE_TOKEN,
@@ -88,7 +87,7 @@
                      rop.JIT_DEBUG, rop.KEEPALIVE,
                      rop.QUASIIMMUT_FIELD, rop.RECORD_KNOWN_CLASS,
                      ):
-            self.newops.append(op)
+            self.newop(op)
             return
         # ----------  fall-back  ----------
         # Check that none of the ops handled here can collect.
@@ -112,12 +111,12 @@
         # group together several stm_reads then we can save one
         # instruction; if delayed over a cond_call_gc_wb then we can
         # omit the stm_read completely; ...
-        self.newops.append(op)
+        self.newop(op)
         v_ptr = op.getarg(0)
         if (v_ptr not in self.read_barrier_applied and
             v_ptr not in self.write_barrier_applied):
             op1 = ResOperation(rop.STM_READ, [v_ptr], None)
-            self.newops.append(op1)
+            self.newop(op1)
             self.read_barrier_applied[v_ptr] = None
 
     def add_dummy_allocation(self):
@@ -137,33 +136,31 @@
 
 
     @specialize.arg(1)
-    def _do_stm_call(self, funcname, args, result, stm_location):
+    def _do_stm_call(self, funcname, args, result):
         addr = self.gc_ll_descr.get_malloc_fn_addr(funcname)
         descr = getattr(self.gc_ll_descr, funcname + '_descr')
         op1 = ResOperation(rop.CALL, [ConstInt(addr)] + args,
                            result, descr=descr)
-        op1.stm_location = stm_location
-        self.newops.append(op1)
+        self.newop(op1)
 
     def fallback_inevitable(self, op):
         if not self.always_inevitable:
             self.emitting_an_operation_that_can_collect()
-            self._do_stm_call('stm_try_inevitable', [], None,
-                              op.stm_location)
+            self._do_stm_call('stm_try_inevitable', [], None)
             self.always_inevitable = True
-        self.newops.append(op)
+        self.newop(op)
         debug_print("fallback for", op.repr())
 
     def maybe_handle_raw_accesses(self, op):
         descr = op.getdescr()
         assert isinstance(descr, FieldDescr)
         if descr.stm_dont_track_raw_accesses:
-            self.newops.append(op)
+            self.newop(op)
             return True
         return False
 
     def handle_setters_for_pure_fields(self, op, targetindex):
         val = op.getarg(targetindex)
         if self.must_apply_write_barrier(val):
-            self.gen_write_barrier(val, op.stm_location)
-        self.newops.append(op)
+            self.gen_write_barrier(val)
+        self.newop(op)
diff --git a/rpython/jit/backend/llsupport/test/test_stmrewrite.py 
b/rpython/jit/backend/llsupport/test/test_stmrewrite.py
--- a/rpython/jit/backend/llsupport/test/test_stmrewrite.py
+++ b/rpython/jit/backend/llsupport/test/test_stmrewrite.py
@@ -1256,17 +1256,30 @@
         guard_not_forced() [] {55}
         """, """
         [i0, f0]
-        i1 = getfield_raw(ConstClass(frame_info), descr=jfi_frame_depth)
-        p1 = call_malloc_nursery_varsize_frame(i1)
-        setfield_gc(p1, 0, descr=tiddescr)
-        setfield_gc(p1, i1, descr=framelendescr)
-        setfield_gc(p1, ConstClass(frame_info), descr=jf_frame_info)
-        setarrayitem_gc(p1, 0, i0, descr=signedframedescr)
-        setarrayitem_gc(p1, 1, f0, descr=floatframedescr)
+        i1 = getfield_raw(ConstClass(frame_info), descr=jfi_frame_depth) {54}
+        p1 = call_malloc_nursery_varsize_frame(i1) {54}
+        setfield_gc(p1, 0, descr=tiddescr) {54}
+        setfield_gc(p1, i1, descr=framelendescr) {54}
+        setfield_gc(p1, ConstClass(frame_info), descr=jf_frame_info) {54}
+        setarrayitem_gc(p1, 0, i0, descr=signedframedescr) {54}
+        setarrayitem_gc(p1, 1, f0, descr=floatframedescr) {54}
         i3 = call_assembler(p1, descr=casmdescr) {54}
         guard_not_forced() [] {55}
         """)
 
+    def test_stm_location_4(self):
+        self.check_rewrite("""
+            [p1, i2, p3]
+            debug_merge_point() {81}
+            i3 = int_add(i2, 5)
+            setarrayitem_gc(p1, i3, p3, descr=cdescr)
+        """, """
+            [p1, i2, p3]
+            i3 = int_add(i2, 5) {81}
+            cond_call_gc_wb_array(p1, i3, descr=wbdescr) {81}
+            setarrayitem_gc(p1, i3, p3, descr=cdescr) {81}
+        """)
+
     def test_stm_should_break_transaction_no_malloc(self):
         self.check_rewrite("""
         []
diff --git a/rpython/jit/metainterp/pyjitpl.py 
b/rpython/jit/metainterp/pyjitpl.py
--- a/rpython/jit/metainterp/pyjitpl.py
+++ b/rpython/jit/metainterp/pyjitpl.py
@@ -1159,8 +1159,6 @@
             loc = jitdriver_sd.warmstate.get_location_str(greenkey)
             debug_print(loc)
         args = [ConstInt(jd_index), ConstInt(portal_call_depth), 
ConstInt(current_call_id)] + greenkey
-        self.metainterp.history.record(rop.DEBUG_MERGE_POINT, args, None)
-        #
         if self.metainterp.staticdata.config.translation.stm:
             report_location = jitdriver_sd.stm_report_location
             if report_location is not None:
@@ -1169,6 +1167,8 @@
                 ref = greenkey[idx_ref].getref_base()
                 location = StmLocation(num, ref)
                 self.metainterp.history.stm_location = location
+        #
+        self.metainterp.history.record(rop.DEBUG_MERGE_POINT, args, None)
 
     @arguments("box", "label")
     def opimpl_goto_if_exception_mismatch(self, vtablebox, next_exc_target):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to