[pypy-svn] r65742 - pypy/branch/pyjitpl5/pypy/jit/backend/x86

arigo at codespeak.net arigo at codespeak.net
Thu Jun 11 18:31:00 CEST 2009


Author: arigo
Date: Thu Jun 11 18:30:59 2009
New Revision: 65742

Modified:
   pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py
   pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py
Log:
Merge r65740 and r65741 from pyjitpl5-experiments:

Found a couple of issues related to compiling the x86 backend with the
hybrid GC:
    
    * _exception_bck

    * fail_boxes, fixed by separating it into two lists, one containing
      non-GC and one containing GC stuff.



Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py	Thu Jun 11 18:30:59 2009
@@ -1,7 +1,7 @@
 import sys, os
 import ctypes
 from pypy.jit.backend.x86 import symbolic
-from pypy.jit.metainterp.history import Const, Box, BoxPtr
+from pypy.jit.metainterp.history import Const, Box, BoxPtr, PTR
 from pypy.rpython.lltypesystem import lltype, rffi, ll2ctypes, rstr, llmemory
 from pypy.rpython.lltypesystem.rclass import OBJECT
 from pypy.rpython.lltypesystem.lloperation import llop
@@ -99,14 +99,21 @@
         self._exception_addr = 0
         self.mcstack = MachineCodeStack()
         self.logger = x86Logger()
+        self.fail_boxes_int = lltype.malloc(lltype.GcArray(lltype.Signed),
+                                            MAX_FAIL_BOXES, zero=True)
+        self.fail_boxes_ptr = lltype.malloc(lltype.GcArray(llmemory.GCREF),
+                                            MAX_FAIL_BOXES, zero=True)
 
     def make_sure_mc_exists(self):
         if self.mc is None:
             from pypy.jit.backend.x86.runner import ConstDescr3
 
-            self.fail_boxes = lltype.malloc(rffi.CArray(lltype.Signed),
-                                            MAX_FAIL_BOXES, flavor='raw')
-            self.fail_box_addr = self.cpu.cast_ptr_to_int(self.fail_boxes)
+            rffi.cast(lltype.Signed, self.fail_boxes_int)   # workaround
+            rffi.cast(lltype.Signed, self.fail_boxes_ptr)   # workaround
+            self.fail_box_int_addr = rffi.cast(lltype.Signed,
+                lltype.direct_arrayitems(self.fail_boxes_int))
+            self.fail_box_ptr_addr = rffi.cast(lltype.Signed,
+                lltype.direct_arrayitems(self.fail_boxes_ptr))
 
             self.logger.create_log()
             # we generate the loop body in 'mc'
@@ -206,28 +213,38 @@
                 op.longevity = None
                 self.sanitize_tree(op.suboperations)
 
-    def assemble_bootstrap_code(self, jumpaddr, arglocs, framesize):
+    def assemble_bootstrap_code(self, jumpaddr, arglocs, args, framesize):
         self.make_sure_mc_exists()
         addr = self.mc.tell()
         #if self.gcrootmap:
         self.mc.PUSH(ebp)
         self.mc.MOV(ebp, esp)
         self.mc.SUB(esp, imm(framesize * WORD))
-        # This uses XCHG to put zeroes in fail_boxes after reading them,
-        # just in case they are pointers.
         for i in range(len(arglocs)):
             loc = arglocs[i]
             if not isinstance(loc, REG):
-                self.mc.XOR(ecx, ecx)
-                self.mc.XCHG(ecx,
-                             addr_add(imm(self.fail_box_addr), imm(i*WORD)))
+                if args[i].type == PTR:
+                    # This uses XCHG to put zeroes in fail_boxes_ptr after
+                    # reading them
+                    self.mc.XOR(ecx, ecx)
+                    self.mc.XCHG(ecx, addr_add(imm(self.fail_box_ptr_addr),
+                                               imm(i*WORD)))
+                else:
+                    self.mc.MOV(ecx, addr_add(imm(self.fail_box_int_addr),
+                                              imm(i*WORD)))
                 self.mc.MOV(loc, ecx)
         for i in range(len(arglocs)):
             loc = arglocs[i]
             if isinstance(loc, REG):
-                self.mc.XOR(loc, loc)
-                self.mc.XCHG(loc,
-                             addr_add(imm(self.fail_box_addr), imm(i*WORD)))
+                if args[i].type == PTR:
+                    # This uses XCHG to put zeroes in fail_boxes_ptr after
+                    # reading them
+                    self.mc.XOR(loc, loc)
+                    self.mc.XCHG(loc, addr_add(imm(self.fail_box_ptr_addr),
+                                               imm(i*WORD)))
+                else:
+                    self.mc.MOV(loc, addr_add(imm(self.fail_box_int_addr),
+                                              imm(i*WORD)))
         self.mc.JMP(rel32(jumpaddr))
         self.mc.done()
         return addr
@@ -723,15 +740,23 @@
         for i in range(len(locs)):
             loc = locs[i]
             if isinstance(loc, REG):
-                self.mc.MOV(addr_add(imm(self.fail_box_addr), imm(i*WORD)), loc)
+                if op.args[i].type == PTR:
+                    base = self.fail_box_ptr_addr
+                else:
+                    base = self.fail_box_int_addr
+                self.mc.MOV(addr_add(imm(base), imm(i*WORD)), loc)
         for i in range(len(locs)):
             loc = locs[i]
             if not isinstance(loc, REG):
+                if op.args[i].type == PTR:
+                    base = self.fail_box_ptr_addr
+                else:
+                    base = self.fail_box_int_addr
                 self.mc.MOV(eax, loc)
-                self.mc.MOV(addr_add(imm(self.fail_box_addr), imm(i*WORD)), eax)
+                self.mc.MOV(addr_add(imm(base), imm(i*WORD)), eax)
         if self.debug_markers:
             self.mc.MOV(eax, imm(pos))
-            self.mc.MOV(addr_add(imm(self.fail_box_addr),
+            self.mc.MOV(addr_add(imm(self.fail_box_int_addr),
                                  imm(len(locs) * WORD)),
                                  eax)
         if exc:

Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py	Thu Jun 11 18:30:59 2009
@@ -91,7 +91,6 @@
             
             self.current_interpreter._store_exception = _store_exception
         TP = lltype.GcArray(llmemory.GCREF)
-        self.keepalives = []
         self._bootstrap_cache = {}
         self._guard_list = []
         self._compiled_ops = {}
@@ -237,11 +236,14 @@
         # key is locations of arguments
         key = loop._x86_compiled
         try:
-            return self._bootstrap_cache[key]
+            return self._bootstrap_cache[key]     # XXX instead of a dict,
+                                                  # just set 'func' as an
+                                                  # attribute of 'loop'
         except KeyError:
             arglocs = loop.arglocs
             addr = self.assembler.assemble_bootstrap_code(loop._x86_compiled,
                                                           arglocs,
+                                                          loop.inputargs,
                                                           loop._x86_stack_depth)
             # passing arglist as the only arg
             func = rffi.cast(lltype.Ptr(self.BOOTSTRAP_TP), addr)
@@ -253,12 +255,12 @@
             return BoxPtr(lltype.nullptr(llmemory.GCREF.TO))
         return BoxInt(0)
     
-    def _get_loop_for_call(self, argnum, calldescr, ptr):
+    def _get_loop_for_call(self, args, calldescr, ptr):
         try:
             return self.generated_mps[calldescr]
         except KeyError:
             pass
-        args = [BoxInt() for i in range(argnum + 1)]
+        args = [arg.clonebox() for arg in args]
         result = self._new_box(ptr)
         operations = [
             ResOperation(rop.CALL, args, result, calldescr),
@@ -284,30 +286,26 @@
         self._guard_index = guard_index # for tests
         op = self._guard_list[guard_index]
         if verbose:
-            print "Leaving at: %d" % self.assembler.fail_boxes[len(op.args)]
+            print "Leaving at: %d" % self.assembler.fail_boxes_int[
+                len(op.args)]
         return op
 
     def set_future_value_int(self, index, intvalue):
         assert index < MAX_FAIL_BOXES, "overflow!"
-        self.assembler.fail_boxes[index] = intvalue
+        self.assembler.fail_boxes_int[index] = intvalue
 
     def set_future_value_ptr(self, index, ptrvalue):
         assert index < MAX_FAIL_BOXES, "overflow!"
-        if not we_are_translated():
-            self.keepalives.append(ptrvalue)
-        else:
-            pass    # Boehm looks inside fail_boxes (XXX)
-        intvalue = self.cast_gcref_to_int(ptrvalue)
-        self.assembler.fail_boxes[index] = intvalue
+        self.assembler.fail_boxes_ptr[index] = ptrvalue
 
     def get_latest_value_int(self, index):
-        return self.assembler.fail_boxes[index]
+        return self.assembler.fail_boxes_int[index]
 
     def get_latest_value_ptr(self, index):
-        intvalue = self.assembler.fail_boxes[index]
-        ptrvalue = self.cast_int_to_gcref(intvalue)
-        # clear after reading (-1 instead of 0, to crash if still used)
-        self.assembler.fail_boxes[index] = -1
+        ptrvalue = self.assembler.fail_boxes_ptr[index]
+        # clear after reading
+        self.assembler.fail_boxes_ptr[index] = lltype.nullptr(
+            llmemory.GCREF.TO)
         return ptrvalue
 
     def execute_call(self, loop, func, verbose):
@@ -325,8 +323,6 @@
             #                 rffi.cast(lltype.Signed, func))
             res = func()
             #llop.debug_print(lltype.Void, "<<<< Back")
-            if not we_are_translated():
-                del self.keepalives[:]
             self.reraise_caught_exception()
         finally:
             if not self.translate_support_code:
@@ -575,7 +571,7 @@
         assert isinstance(calldescr, ConstDescr3)
         num_args, size, ptr = self.unpack_calldescr(calldescr)
         assert num_args == len(args) - 1
-        loop = self._get_loop_for_call(num_args, calldescr, ptr)
+        loop = self._get_loop_for_call(args, calldescr, ptr)
         history.set_future_values(self, args)
         self.execute_operations(loop, verbose=False)
         # Note: if an exception is set, the rest of the code does a bit of



More information about the Pypy-commit mailing list