[pypy-svn] r67356 - pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86

arigo at codespeak.net arigo at codespeak.net
Mon Aug 31 14:28:29 CEST 2009


Author: arigo
Date: Mon Aug 31 14:28:28 2009
New Revision: 67356

Modified:
   pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py
   pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py
Log:
Fix the x86 backend.


Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py	(original)
+++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/assembler.py	Mon Aug 31 14:28:28 2009
@@ -142,14 +142,6 @@
                 ll_new_unicode = gc_ll_descr.get_funcptr_for_newunicode()
                 self.malloc_unicode_func_addr = rffi.cast(lltype.Signed,
                                                           ll_new_unicode)
-            # for moving GCs, the array used to hold the address of GC objects
-            # that appear as ConstPtr.
-            if gc_ll_descr.moving_gc:
-                from pypy.jit.backend.llsupport.descr import GcPtrFieldDescr
-                self.gcrefs = gc_ll_descr.GcRefList()
-                self.single_gcref_descr = GcPtrFieldDescr(0)
-            else:
-                self.gcrefs = None
             self.gcrootmap = gc_ll_descr.gcrootmap
             if self.gcrootmap:
                 self.gcrootmap.initialize()
@@ -569,6 +561,7 @@
             assert 0, itemsize
 
     genop_discard_setfield_raw = genop_discard_setfield_gc
+    genop_discard_setarrayitem_raw = genop_discard_setarrayitem_gc
 
     def genop_strlen(self, op, arglocs, resloc):
         base_loc = arglocs[0]
@@ -583,9 +576,9 @@
         self.mc.MOV(resloc, addr_add_const(base_loc, ofs_length))
 
     def genop_arraylen_gc(self, op, arglocs, resloc):
-        ofs = self.cpu.gc_ll_descr.array_length_ofs
         base_loc, ofs_loc = arglocs
-        self.mc.MOV(resloc, addr_add_const(base_loc, ofs))
+        assert isinstance(ofs_loc, IMM32)
+        self.mc.MOV(resloc, addr_add_const(base_loc, ofs_loc.value))
 
     def genop_strgetitem(self, op, arglocs, resloc):
         base_loc, ofs_loc = arglocs
@@ -773,42 +766,34 @@
 
     genop_call_pure = genop_call
 
-    def genop_cond_call(self, op, arglocs, resloc):
-        sizeloc = arglocs[0]
-        assert isinstance(sizeloc, IMM32)
-        size = sizeloc.value
+    def genop_discard_cond_call_gc_wb(self, op, arglocs):
         # use 'mc._mc' directly instead of 'mc', to avoid
         # bad surprizes if the code buffer is mostly full
-        loc_cond           = arglocs[1]
-        loc_mask           = arglocs[2]
-        loc_value_if_false = arglocs[3]
+        loc_cond = arglocs[0]
+        loc_mask = arglocs[1]
         mc = self.mc._mc
         mc.TEST(loc_cond, loc_mask)
         mc.write('\x74\x00')             # JZ after_the_call
         jz_location = mc.get_relative_pos()
         # the following is supposed to be the slow path, so whenever possible
         # we choose the most compact encoding over the most efficient one.
-        for i in range(len(arglocs)-1, 4, -1):
+        for i in range(len(arglocs)-1, 2, -1):
             mc.PUSH(arglocs[i])
-        mc.CALL(rel32(op.args[3].getint()))
-        if size == 1:
-            mc.MOVZX(resloc, al)
-        elif size == 2:
-            mc.MOVZX(resloc, eax)     # actually reads the AX part only
-        elif resloc is not None and resloc is not eax:
-            mc.XCHG(eax, resloc)
+        mc.CALL(rel32(op.args[2].getint()))
         pop_count = 0
-        for i in range(5, len(arglocs)):
+        for i in range(3, len(arglocs)):
             loc = arglocs[i]
             pop_count += 1
-            if loc is not resloc and isinstance(loc, REG):
+            if isinstance(loc, REG):
                 while pop_count > 0:
                     mc.POP(loc)
                     pop_count -= 1
         if pop_count:
             mc.ADD(esp, imm(WORD * pop_count))
         # patch the JZ above
-        mc.overwrite(jz_location-1, chr(mc.get_relative_pos() - jz_location))
+        offset = mc.get_relative_pos() - jz_location
+        assert 0 < offset <= 127
+        mc.overwrite(jz_location-1, chr(offset))
 
     def not_implemented_op_discard(self, op, arglocs):
         print "not implemented operation: %s" % op.getopname()

Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py
==============================================================================
--- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py	(original)
+++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/regalloc.py	Mon Aug 31 14:28:28 2009
@@ -59,7 +59,8 @@
         self.assembler = assembler
         self.translate_support_code = translate_support_code
         if regalloc is None:
-            self._rewrite_const_ptrs(tree.operations)
+            gc_ll_descr = self.assembler.cpu.gc_ll_descr
+            gc_ll_descr.rewrite_assembler(self, tree.operations)
             self.tree = tree
             self.reg_bindings = newcheckdict()
             self.stack_bindings = newcheckdict()
@@ -215,38 +216,6 @@
         self.max_stack_depth = max(self.max_stack_depth,
                                    self.current_stack_depth + 1)
 
-    def _rewrite_const_ptrs(self, operations):
-        # Idea: when running on a moving GC, we can't (easily) encode
-        # the ConstPtrs in the assembler, because they can move at any
-        # point in time.  Instead, we store them in 'gcrefs.list', a GC
-        # but nonmovable list; and here, we modify 'operations' to
-        # replace direct usage of ConstPtr with a BoxPtr loaded by a
-        # GETFIELD_RAW from the array 'gcrefs.list'.
-        gcrefs = self.assembler.gcrefs
-        if gcrefs is None:
-            return
-        single_gcref_descr = self.assembler.single_gcref_descr
-        newops = []
-        for op in operations:
-            if op.opnum == rop.DEBUG_MERGE_POINT:
-                continue
-            for i in range(len(op.args)):
-                v = op.args[i]
-                if (isinstance(v, ConstPtr) and v.value
-                                            and rgc.can_move(v.value)):
-                    box = BoxPtr(v.value)
-                    addr = gcrefs.get_address_of_gcref(v.value)
-                    addr = rffi.cast(lltype.Signed, addr)
-                    newops.append(ResOperation(rop.GETFIELD_RAW,
-                                               [ConstInt(addr)], box,
-                                               single_gcref_descr))
-                    op.args[i] = box
-            if op.is_guard():
-                self._rewrite_const_ptrs(op.suboperations)
-            newops.append(op)
-        del operations[:]
-        operations.extend(newops)
-
     def _compute_vars_longevity(self, inputargs, operations):
         # compute a dictionary that maps variables to index in
         # operations that is a "last-time-seen"
@@ -725,31 +694,18 @@
 
     consider_call_pure = consider_call
 
-    def consider_cond_call(self, op, ignored):
-        calldescr = op.descr
-        assert isinstance(calldescr, BaseCallDescr)
-        v_cond = op.args[0]
-        v_mask = op.args[1]
-        v_value_if_false = op.args[2]
-        if op.result is not None:
-            resloc = self.force_result_in_reg(op.result, v_value_if_false, [])
-        else:
-            resloc = None
-        condloc = self.loc(v_cond)
-        arglocs = [resloc] + [self.loc(arg) for arg in op.args[3:]]
+    def consider_cond_call_gc_wb(self, op, ignored):
+        assert op.result is None
+        arglocs = [self.loc(arg) for arg in op.args]
         # add eax, ecx and edx as extra "arguments" to ensure they are
-        # saved and restored.  Don't add them if they are equal to resloc!
+        # saved and restored.
         for v, reg in self.reg_bindings.items():
             if ((reg is eax or reg is ecx or reg is edx)
                 and self.longevity[v][1] > self.position
-                and reg not in arglocs):
+                and reg not in arglocs[3:]):
                 arglocs.append(reg)
-        size = calldescr.get_result_size(self.translate_support_code)
-        self.Perform(op,
-                     [imm(size), condloc, convert_to_imm(v_mask)] + arglocs,
-                     resloc)
-        self.eventually_free_var(v_cond)
-        self.eventually_free_vars(op.args[3:])
+        self.PerformDiscard(op, arglocs)
+        self.eventually_free_vars(op.args)
 
     def consider_new(self, op, ignored):
         args = self.assembler.cpu.gc_ll_descr.args_for_new(op.descr)
@@ -841,7 +797,7 @@
         ptr = fielddescr.is_pointer_field()
         return imm(ofs), imm(size), ptr
 
-    def _common_consider_setfield(self, op, ignored, raw):
+    def consider_setfield_gc(self, op, ignored):
         ofs_loc, size_loc, ptr = self._unpack_fielddescr(op.descr)
         assert isinstance(size_loc, IMM32)
         if size_loc.value == 1:
@@ -851,20 +807,10 @@
         base_loc = self.make_sure_var_in_reg(op.args[0], op.args)
         value_loc = self.make_sure_var_in_reg(op.args[1], op.args,
                                               need_lower_byte=need_lower_byte)
-        if ptr:
-            if raw:
-                print "Setfield of raw structure with gc pointer"
-                assert False
-            gc_ll_descr = self.assembler.cpu.gc_ll_descr
-            gc_ll_descr.gen_write_barrier(self.assembler, base_loc, value_loc)
         self.eventually_free_vars(op.args)
         self.PerformDiscard(op, [base_loc, ofs_loc, size_loc, value_loc])
 
-    def consider_setfield_gc(self, op, ignored):
-        self._common_consider_setfield(op, ignored, raw=False)
-    
-    def consider_setfield_raw(self, op, ignored):
-        self._common_consider_setfield(op, ignored, raw=True)
+    consider_setfield_raw = consider_setfield_gc
 
     def consider_strsetitem(self, op, ignored):
         base_loc = self.make_sure_var_in_reg(op.args[0], op.args)
@@ -886,13 +832,12 @@
         value_loc = self.make_sure_var_in_reg(op.args[2], op.args,
                                               need_lower_byte=need_lower_byte)
         ofs_loc = self.make_sure_var_in_reg(op.args[1], op.args)
-        if ptr:
-            gc_ll_descr = self.assembler.cpu.gc_ll_descr
-            gc_ll_descr.gen_write_barrier(self.assembler, base_loc, value_loc)
         self.eventually_free_vars(op.args)
         self.PerformDiscard(op, [base_loc, ofs_loc, value_loc,
                                  imm(scale), imm(ofs)])
 
+    consider_setarrayitem_raw = consider_setarrayitem_gc
+
     def consider_getfield_gc(self, op, ignored):
         ofs_loc, size_loc, _ = self._unpack_fielddescr(op.descr)
         base_loc = self.make_sure_var_in_reg(op.args[0], op.args)
@@ -952,7 +897,9 @@
     consider_unicodelen = consider_strlen
 
     def consider_arraylen_gc(self, op, ignored):
-        _, ofs, _ = self._unpack_arraydescr(op.descr)
+        arraydescr = op.descr
+        assert isinstance(arraydescr, BaseArrayDescr)
+        ofs = arraydescr.get_ofs_length(self.translate_support_code)
         base_loc = self.make_sure_var_in_reg(op.args[0], op.args)
         self.eventually_free_vars(op.args)
         result_loc = self.force_allocate_reg(op.result, [])



More information about the Pypy-commit mailing list