Commits

Armin Rigo committed 92bc41f

in-progress

  • Participants
  • Parent commits 469c780
  • Branches stm-jit

Comments (0)

Files changed (6)

File pypy/jit/backend/llsupport/stmrewrite.py

             self.newops.append(op)
             return
         lst[0] = self.unconstifyptr(lst[0])
-        self.newops.append(OP_STM_READ_BEFORE)
+        write_barrier_descr = self.gc_ll_descr.write_barrier_descr
+        op_before = ResOperation(rop.STM_READ_BEFORE, [lst[0]], None,
+                                 descr=write_barrier_descr)
+        op_after  = ResOperation(rop.STM_READ_AFTER, [lst[0]], None)
+        self.newops.append(op_before)
         self.newops.append(op.copy_and_change(op.getopnum(), args=lst))
-        self.newops.append(OP_STM_READ_AFTER)
+        self.newops.append(op_after)
 
     def handle_copystrcontent(self, op):
         # first, a write barrier on the target string
             self.newops.append(op1)
             self.always_inevitable = True
         self.newops.append(op)
-
-
-OP_STM_READ_BEFORE = ResOperation(rop.STM_READ_BEFORE, [], None)
-OP_STM_READ_AFTER  = ResOperation(rop.STM_READ_AFTER, [], None)

File pypy/jit/backend/llsupport/test/test_stmrewrite.py

             jump(p2)
         """, """
             [p1]
-            stm_read_before()
+            stm_read_before(p1, descr=wbdescr)
             p2 = getfield_gc(p1, descr=tzdescr)
-            stm_read_after()
+            stm_read_after(p1)
             jump(p2)
         """)
 
         """, """
             [p1]
             p3 = same_as(ConstPtr(t))
-            stm_read_before()
+            stm_read_before(p3, descr=wbdescr)
             p2 = getfield_gc(p3, descr=tzdescr)
-            stm_read_after()
+            stm_read_after(p3)
             jump(p2)
         """)
 
             jump(i3)
         """, """
             [p1, i2]
-            stm_read_before()
+            stm_read_before(p1, descr=wbdescr)
             i3 = getarrayitem_gc(p1, i2, descr=adescr)
-            stm_read_after()
+            stm_read_after(p1)
             jump(i3)
         """)
 
             jump(i3)
         """, """
             [p1, i2]
-            stm_read_before()
+            stm_read_before(p1, descr=wbdescr)
             i3 = getinteriorfield_gc(p1, i2, descr=adescr)
-            stm_read_after()
+            stm_read_after(p1)
             jump(i3)
         """)
 
             jump(p2, i2)
         """, """
             [p1]
-            stm_read_before()
+            stm_read_before(p1, descr=wbdescr)
             p2 = getfield_gc(p1, descr=tzdescr)
             i2 = getfield_gc(p1, descr=tydescr)
-            stm_read_after()
+            stm_read_after(p1)
             jump(p2, i2)
         """)
 
             jump(p2, i2)
         """, """
             [p1]
-            stm_read_before()
+            stm_read_before(p1, descr=wbdescr)
             p2 = getfield_gc(p1, descr=tzdescr)
-            stm_read_after()
-            stm_read_before()
+            stm_read_after(p1)
+            stm_read_before(p2, descr=wbdescr)
             i2 = getfield_gc(p2, descr=tydescr)
-            stm_read_after()
+            stm_read_after(p2)
             jump(p2, i2)
         """)
 
             jump(p2, i2)
         """, """
             [p1]
-            stm_read_before()
+            stm_read_before(p1, descr=wbdescr)
             p2 = getfield_gc(p1, descr=tzdescr)
             i2 = getfield_gc(p1, descr=tydescr)
-            stm_read_after()
+            stm_read_after(p1)
             guard_nonnull(p2) [i1]
             jump(p2, i2)
         """)
             jump(p2, i2)
         """, """
             [p1]
-            stm_read_before()
+            stm_read_before(p1, descr=wbdescr)
             p2 = getfield_gc(p1, descr=tzdescr)
-            stm_read_after()
+            stm_read_after(p1)
             call(123)
-            stm_read_before()
+            stm_read_before(p1, descr=wbdescr)
             i2 = getfield_gc(p1, descr=tydescr)
-            stm_read_after()
+            stm_read_after(p1)
             jump(p2, i2)
         """)
 
         """, """
             [p1, p2, i1, i2, i3]
             cond_call_gc_wb(p2, 0, descr=wbdescr)
-            stm_read_before()
+            stm_read_before(p1, descr=wbdescr)
             copystrcontent(p1, p2, i1, i2, i3)
-            stm_read_after()
+            stm_read_after(p1)
             jump()
         """)
 

File pypy/jit/backend/x86/assembler.py

 
     genop_discard_cond_call_gc_wb_array = genop_discard_cond_call_gc_wb
 
+    def genop_discard_stm_read_before(self, op, arglocs):
+        descr = op.getdescr()
+        if we_are_translated():
+            cls = self.cpu.gc_ll_descr.has_write_barrier_class()
+            assert cls is not None and isinstance(descr, cls)
+        # 
+        loc, loc_version = arglocs
+        assert loc is edx
+        assert loc_version is eax
+        # XXX hard-coded for now: the version is the second WORD in objects
+        self.mc.MOV_rm(loc_version.value, (loc.value, WORD))
+        #
+        mask = descr.jit_wb_if_flag_singlebyte    # test GCFLAG_GLOBAL
+        self.mc.TEST8_mi((loc.value, descr.jit_wb_if_flag_byteofs), mask)
+        self.mc.J_il8(rx86.Conditions['Z'], 0) # patched later
+        jz_location = self.mc.get_relative_pos()
+
+        # call interface: 'loc' is passed in edx; 'loc_version' is
+        # returned in eax.
+        self.mc.CALL(imm(self.stm_read_before_slowpath))
+
+        # patch the JZ above
+        offset = self.mc.get_relative_pos() - jz_location
+        assert 0 < offset <= 127
+        self.mc.overwrite(jz_location-1, chr(offset))
+
+    def genop_discard_stm_read_after(self, op, arglocs):
+        loc, loc_version, loc_position = arglocs
+        assert isinstance(loc, RegLoc)
+        assert isinstance(loc_version, RegLoc)
+        assert isinstance(loc_position, ImmedLoc)
+        # XXX hard-coded for now: the version is the second WORD in objects
+        self.mc.CMP_rm(loc_version.value, (loc.value, WORD))
+        #
+        # the negative offset of the conditional jump
+        offset = loc_position.value - (self.mc.get_relative_pos() + 2)
+        assert offset < 0
+        if offset >= -128:
+            self.mc.J_il8(rx86.Conditions['NE'], offset)
+        else:
+            # doesn't fit in one byte, use the 4-bytes variant
+            XXX
+
     def not_implemented_op_discard(self, op, arglocs):
         not_implemented("not implemented operation: %s" % op.getopname())
 

File pypy/jit/backend/x86/regalloc.py

     def consider_stm_read_before(self, op):
         self.xrm.before_call(save_all_regs=True)
         self.rm.before_call(save_all_regs=True)
+        self.stm_read_before_position = self.assembler.mc.get_relative_pos()
+        args = op.getarglist()
+        loc = self.rm.make_sure_var_in_reg(args[0], selected_reg=edx)
+        tmpbox_version = TempBox()
+        loc_version = self.rm.force_allocate_reg(tmpbox_version,
+                                                 selected_reg=eax)
+        self.PerformDiscard(op, [loc, loc_version])
+        # tmpbox_version freed only in stm_read_after
+        self.stm_tmpbox_version = tmpbox_version
+
+    def consider_stm_read_after(self, op):
+        tmpbox_version = self.stm_tmpbox_version
+        loc = self.rm.make_sure_var_in_reg(op.getarg(0))
+        loc_version = self.rm.make_sure_var_in_reg(tmpbox_version)
+        loc_position = imm(self.stm_read_before_position)
+        self.PerformDiscard(op, [loc, loc_version, loc_position])
+        self.rm.possibly_free_var(op.getarg(0))
+        self.rm.possibly_free_var(tmpbox_version)
 
     def not_implemented_op(self, op):
         not_implemented("not implemented operation: %s" % op.getopname())

File pypy/jit/backend/x86/test/test_stm_integration.py

     def test_stm_read_before_spills_all(self):
         # for now, stm_read_before() first spills all registers
         ops = '''
-        [i1, i2]
+        [i1, i2, p1]
         i3 = int_add(i1, i2)
-        stm_read_before()
+        stm_read_before(p1, descr=wbdescr)
         escape(i3)         # assert i3 was spilled
         finish(i3)
         '''

File pypy/jit/metainterp/resoperation.py

     'QUASIIMMUT_FIELD/1d',    # [objptr], descr=SlowMutateDescr
     'RECORD_KNOWN_CLASS/2',   # [objptr, clsptr]
     'KEEPALIVE/1',
-    'STM_READ_BEFORE/0',      # inserted by backend/llsupport/stmrewrite
-    'STM_READ_AFTER/0',       # inserted by backend/llsupport/stmrewrite
+    'STM_READ_BEFORE/1d',     # inserted by backend/llsupport/stmrewrite
+    'STM_READ_AFTER/1',       # inserted by backend/llsupport/stmrewrite
 
     '_CANRAISE_FIRST', # ----- start of can_raise operations -----
     '_CALL_FIRST',