Author: Armin Rigo <[email protected]>
Branch: remove-globals-in-jit
Changeset: r58924:3180d3717743
Date: 2012-11-15 12:00 +0100
http://bitbucket.org/pypy/pypy/changeset/3180d3717743/

Log:    In-progress: kill kill kill failargs_xyz and related data on the
        Assembler386 class.

diff --git a/pypy/jit/backend/llsupport/descr.py 
b/pypy/jit/backend/llsupport/descr.py
--- a/pypy/jit/backend/llsupport/descr.py
+++ b/pypy/jit/backend/llsupport/descr.py
@@ -226,15 +226,21 @@
     def repr_of_descr(self):
         return '<InteriorFieldDescr %s>' % self.fielddescr.repr_of_descr()
 
-def get_interiorfield_descr(gc_ll_descr, ARRAY, name):
+def get_interiorfield_descr(gc_ll_descr, ARRAY, name, arrayfieldname=None):
+    # can be used either with a GcArray of Structs, or with a GcStruct
+    # containing an inlined GcArray of Structs (then arrayfieldname != None).
     cache = gc_ll_descr._cache_interiorfield
     try:
-        return cache[(ARRAY, name)]
+        return cache[(ARRAY, name, arrayfieldname)]
     except KeyError:
         arraydescr = get_array_descr(gc_ll_descr, ARRAY)
-        fielddescr = get_field_descr(gc_ll_descr, ARRAY.OF, name)
+        if arrayfieldname is None:
+            REALARRAY = ARRAY
+        else:
+            REALARRAY = getattr(ARRAY, arrayfieldname)
+        fielddescr = get_field_descr(gc_ll_descr, REALARRAY.OF, name)
         descr = InteriorFieldDescr(arraydescr, fielddescr)
-        cache[(ARRAY, name)] = descr
+        cache[(ARRAY, name, arrayfieldname)] = descr
         return descr
 
 # ____________________________________________________________
diff --git a/pypy/jit/backend/llsupport/gc.py b/pypy/jit/backend/llsupport/gc.py
--- a/pypy/jit/backend/llsupport/gc.py
+++ b/pypy/jit/backend/llsupport/gc.py
@@ -10,7 +10,7 @@
 from pypy.jit.codewriter import heaptracker
 from pypy.jit.metainterp.history import ConstPtr, AbstractDescr
 from pypy.jit.metainterp.resoperation import ResOperation, rop
-from pypy.jit.backend.llsupport import symbolic
+from pypy.jit.backend.llsupport import symbolic, jitframe
 from pypy.jit.backend.llsupport.symbolic import WORD
 from pypy.jit.backend.llsupport.descr import SizeDescr, ArrayDescr
 from pypy.jit.backend.llsupport.descr import GcCache, get_field_descr
@@ -110,6 +110,15 @@
             self._record_constptrs(op, gcrefs_output_list)
         return newops
 
+    @specialize.memo()
+    def getframedescrs(self, cpu):
+        return (
+            cpu.arraydescrof(jitframe.DEADFRAME),
+            cpu.interiorfielddescrof(jitframe.DEADFRAME, 'int', 'jf_values'),
+            cpu.interiorfielddescrof(jitframe.DEADFRAME, 'ref', 'jf_values'),
+            cpu.interiorfielddescrof(jitframe.DEADFRAME, 'float', 'jf_values'),
+            cpu.fielddescrof(jitframe.DEADFRAME, 'jf_descr'))
+
 # ____________________________________________________________
 
 class GcLLDescr_boehm(GcLLDescription):
diff --git a/pypy/jit/backend/llsupport/jitframe.py 
b/pypy/jit/backend/llsupport/jitframe.py
new file mode 100644
--- /dev/null
+++ b/pypy/jit/backend/llsupport/jitframe.py
@@ -0,0 +1,27 @@
+from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.jit.codewriter import longlong
+
+
+VALUEUNION = lltype.Struct('VALUEUNION',
+                           ('int', lltype.Signed),
+                           ('ref', llmemory.GCREF),
+                           ('float', longlong.FLOATSTORAGE),
+                           hints={'union': True})
+
+DEADFRAME = lltype.GcStruct(
+    'DEADFRAME',
+
+    # Once the execute_token() returns, the field 'jf_descr' stores the
+    # descr of the last executed operation (either a GUARD, or FINISH).
+    # This field is also set immediately before doing CALL_MAY_FORCE
+    # or CALL_ASSEMBLER.
+    ('jf_descr', llmemory.GCREF),
+
+    # For the front-end: a GCREF for the savedata
+    ('jf_savedata', llmemory.GCREF),
+
+    # All values are stored in the following array, for now not very
+    # compactly on 32-bit machines.
+    ('jf_values', lltype.Array(VALUEUNION)))
+
+DEADFRAMEPTR = lltype.Ptr(DEADFRAME)
diff --git a/pypy/jit/backend/llsupport/llmodel.py 
b/pypy/jit/backend/llsupport/llmodel.py
--- a/pypy/jit/backend/llsupport/llmodel.py
+++ b/pypy/jit/backend/llsupport/llmodel.py
@@ -45,7 +45,6 @@
             self._setup_exception_handling_translated()
         else:
             self._setup_exception_handling_untranslated()
-        self.saved_exc_value = lltype.nullptr(llmemory.GCREF.TO)
         self.asmmemmgr = AsmMemoryManager()
         self.setup()
         if translate_support_code:
@@ -119,6 +118,7 @@
 
 
     def _setup_exception_handling_translated(self):
+        xxxxxxxxxxx
 
         def pos_exception():
             addr = llop.get_exception_addr(llmemory.Address)
@@ -132,12 +132,12 @@
             addr = llop.get_exception_addr(llmemory.Address)
             addr.address[0] = llmemory.NULL
             addr = llop.get_exc_value_addr(llmemory.Address)
-            exc_value = rffi.cast(llmemory.GCREF, addr.address[0])
+            exc_value = addr.address[0]
             addr.address[0] = llmemory.NULL
             # from now on, the state is again consistent -- no more RPython
             # exception is set.  The following code produces a write barrier
             # in the assignment to self.saved_exc_value, as needed.
-            self.saved_exc_value = exc_value
+            self.saved_exc_value = rffi.cast(llmemory.GCREF, exc_value)
 
         def save_exception_memoryerr():
             from pypy.rpython.annlowlevel import cast_instance_to_base_ptr
@@ -207,7 +207,8 @@
             f = llhelper(self._ON_JIT_LEAVE_FUNC, self.on_leave_jitted_noexc)
         return rffi.cast(lltype.Signed, f)
 
-    def grab_exc_value(self):
+    def grab_exc_value(self, deadframe):
+        xxx
         exc = self.saved_exc_value
         self.saved_exc_value = lltype.nullptr(llmemory.GCREF.TO)
         return exc
@@ -263,8 +264,9 @@
     def arraydescrof(self, A):
         return get_array_descr(self.gc_ll_descr, A)
 
-    def interiorfielddescrof(self, A, fieldname):
-        return get_interiorfield_descr(self.gc_ll_descr, A, fieldname)
+    def interiorfielddescrof(self, A, fieldname, arrayfieldname=None):
+        return get_interiorfield_descr(self.gc_ll_descr, A, fieldname,
+                                       arrayfieldname)
 
     def unpack_arraydescr(self, arraydescr):
         assert isinstance(arraydescr, ArrayDescr)
diff --git a/pypy/jit/backend/llsupport/rewrite.py 
b/pypy/jit/backend/llsupport/rewrite.py
--- a/pypy/jit/backend/llsupport/rewrite.py
+++ b/pypy/jit/backend/llsupport/rewrite.py
@@ -1,10 +1,12 @@
 import sys
 from pypy.rlib.rarithmetic import ovfcheck
+from pypy.jit.metainterp import history
 from pypy.jit.metainterp.history import ConstInt, BoxPtr, ConstPtr
 from pypy.jit.metainterp.resoperation import ResOperation, rop
 from pypy.jit.codewriter import heaptracker
 from pypy.jit.backend.llsupport.symbolic import WORD
 from pypy.jit.backend.llsupport.descr import SizeDescr, ArrayDescr
+from pypy.jit.backend.llsupport import jitframe
 
 
 class GcRewriterAssembler(object):
@@ -65,6 +67,10 @@
                     continue
             # ----------
             self.newops.append(op)
+        # ---------- FINISH ----------
+        if self.newops[-1].getopnum() == rop.FINISH:
+            self.handle_finish(self.newops.pop())
+        # ----------
         return self.newops
 
     # ----------
@@ -337,3 +343,41 @@
             # assume that "self.gc_ll_descr.minimal_size_in_nursery" is 2 WORDs
             size = max(size, 2 * WORD)
             return (size + WORD-1) & ~(WORD-1)     # round up
+
+    # ----------
+
+    def handle_finish(self, finish_op):
+        v_deadframe = BoxPtr()
+        args_boxes = finish_op.getarglist()     # may contain Consts too
+        #
+        arraydescr, int_descr, ref_descr, float_descr, jf_descr = (
+            self.gc_ll_descr.getframedescrs(self.cpu))
+        #
+        op = ResOperation(rop.NEW_ARRAY,
+                          [ConstInt(len(args_boxes))], v_deadframe,
+                          descr=arraydescr)
+        self.handle_malloc_operation(op)
+        #
+        for i in range(len(args_boxes)):
+            # Generate setinteriorfields to write the args inside the
+            # deadframe object.  Ignore write barriers because it's a
+            # recent object.
+            box = args_boxes[i]
+            if box.type == history.INT: descr = int_descr
+            elif box.type == history.REF: descr = ref_descr
+            elif box.type == history.FLOAT: descr = float_descr
+            else: assert 0, "bad box type?"
+            op = ResOperation(rop.SETINTERIORFIELD_GC,
+                              [v_deadframe, ConstInt(i), box], None,
+                              descr=descr)
+            self.newops.append(op)
+        #
+        # Generate a setfield to write the finish_op's descr.
+        gcref_descr = finish_op.getdescr().hide(self.cpu)
+        op = ResOperation(rop.SETFIELD_GC,
+                          [v_deadframe, ConstPtr(gcref_descr)], None,
+                          descr=jf_descr)
+        self.newops.append(op)
+        #
+        op = ResOperation(rop.FINISH, [v_deadframe], None)
+        self.newops.append(op)
diff --git a/pypy/jit/backend/x86/assembler.py 
b/pypy/jit/backend/x86/assembler.py
--- a/pypy/jit/backend/x86/assembler.py
+++ b/pypy/jit/backend/x86/assembler.py
@@ -30,7 +30,6 @@
 from pypy.rlib.objectmodel import we_are_translated, specialize
 from pypy.jit.backend.x86 import rx86, regloc, codebuf
 from pypy.jit.metainterp.resoperation import rop, ResOperation
-from pypy.jit.backend.x86.support import values_array
 from pypy.jit.backend.x86 import support
 from pypy.rlib.debug import (debug_print, debug_start, debug_stop,
                              have_debug_prints)
@@ -68,16 +67,10 @@
     _regalloc = None
     _output_loop_log = None
 
-    def __init__(self, cpu, translate_support_code=False,
-                            failargs_limit=1000):
+    def __init__(self, cpu, translate_support_code=False):
         self.cpu = cpu
         self.verbose = False
         self.rtyper = cpu.rtyper
-        self.fail_boxes_int = values_array(lltype.Signed, failargs_limit)
-        self.fail_boxes_ptr = values_array(llmemory.GCREF, failargs_limit)
-        self.fail_boxes_float = values_array(longlong.FLOATSTORAGE,
-                                             failargs_limit)
-        self.fail_ebp = 0
         self.loop_run_counters = []
         self.float_const_neg_addr = 0
         self.float_const_abs_addr = 0
@@ -88,18 +81,12 @@
         self.setup_failure_recovery()
         self._debug = False
         self.debug_counter_descr = cpu.fielddescrof(DEBUG_COUNTER, 'i')
-        self.fail_boxes_count = 0
         self.datablockwrapper = None
         self.stack_check_slowpath = 0
         self.propagate_exception_path = 0
         self.gcrootmap_retaddr_forced = 0
         self.teardown()
 
-    def leave_jitted_hook(self):
-        ptrs = self.fail_boxes_ptr.ar
-        llop.gc_assume_young_pointers(lltype.Void,
-                                      llmemory.cast_ptr_to_adr(ptrs))
-
     def set_debug(self, v):
         r = self._debug
         self._debug = v
@@ -1915,8 +1902,6 @@
                 n = self.CODE_HOLE
             mc.writechar(chr(n))
         mc.writechar(chr(self.CODE_STOP))
-        # assert that the fail_boxes lists are big enough
-        assert len(failargs) <= self.fail_boxes_int.SIZE
 
     def rebuild_faillocs_from_descr(self, bytecode):
         from pypy.jit.backend.x86.regalloc import X86FrameManager
@@ -2118,47 +2103,10 @@
         self.failure_recovery_code[exc + 2 * withfloats] = rawstart
         self.mc = None
 
-    def generate_failure(self, fail_index, locs, exc, locs_are_ref):
-        self.mc.begin_reuse_scratch_register()
-        for i in range(len(locs)):
-            loc = locs[i]
-            if isinstance(loc, RegLoc):
-                if loc.is_xmm:
-                    adr = self.fail_boxes_float.get_addr_for_num(i)
-                    self.mc.MOVSD(heap(adr), loc)
-                else:
-                    if locs_are_ref[i]:
-                        adr = self.fail_boxes_ptr.get_addr_for_num(i)
-                    else:
-                        adr = self.fail_boxes_int.get_addr_for_num(i)
-                    self.mc.MOV(heap(adr), loc)
-        for i in range(len(locs)):
-            loc = locs[i]
-            if not isinstance(loc, RegLoc):
-                if ((isinstance(loc, StackLoc) and loc.type == FLOAT) or
-                        isinstance(loc, ConstFloatLoc)):
-                    self.mc.MOVSD(xmm0, loc)
-                    adr = self.fail_boxes_float.get_addr_for_num(i)
-                    self.mc.MOVSD(heap(adr), xmm0)
-                else:
-                    if locs_are_ref[i]:
-                        adr = self.fail_boxes_ptr.get_addr_for_num(i)
-                    else:
-                        adr = self.fail_boxes_int.get_addr_for_num(i)
-                    self.mc.MOV(eax, loc)
-                    self.mc.MOV(heap(adr), eax)
-        self.mc.end_reuse_scratch_register()
-
-        # we call a provided function that will
-        # - call our on_leave_jitted_hook which will mark
-        #   the fail_boxes_ptr array as pointing to young objects to
-        #   avoid unwarranted freeing
-        # - optionally save exception depending on the flag
-        addr = self.cpu.get_on_leave_jitted_int(save_exception=exc)
-        self.mc.CALL(imm(addr))
-
-        self.mc.MOV_ri(eax.value, fail_index)
-
+    def genop_finish(self, op, arglocs, result_loc):
+        [argloc] = arglocs
+        if argloc is not eax:
+            self.mov(argloc, eax)
         # exit function
         self._call_footer()
 
diff --git a/pypy/jit/backend/x86/regalloc.py b/pypy/jit/backend/x86/regalloc.py
--- a/pypy/jit/backend/x86/regalloc.py
+++ b/pypy/jit/backend/x86/regalloc.py
@@ -486,15 +486,9 @@
     consider_guard_isnull = _consider_guard
 
     def consider_finish(self, op):
-        locs = [self.loc(op.getarg(i)) for i in range(op.numargs())]
-        locs_are_ref = [op.getarg(i).type == REF for i in range(op.numargs())]
-        fail_index = self.assembler.cpu.get_fail_descr_number(op.getdescr())
-        # note: no exception should currently be set in llop.get_exception_addr
-        # even if this finish may be an exit_frame_with_exception (in this case
-        # the exception instance is in locs[0]).
-        self.assembler.generate_failure(fail_index, locs, False,
-                                        locs_are_ref)
-        self.possibly_free_vars_for_op(op)
+        loc = self.loc(op.getarg(0))
+        self.Perform(op, [loc], None)
+        self.possibly_free_var(op.getarg(0))
 
     def consider_guard_no_exception(self, op):
         self.perform_guard(op, [], None)
diff --git a/pypy/jit/backend/x86/runner.py b/pypy/jit/backend/x86/runner.py
--- a/pypy/jit/backend/x86/runner.py
+++ b/pypy/jit/backend/x86/runner.py
@@ -49,15 +49,7 @@
         return self.assembler.set_debug(flag)
 
     def setup(self):
-        if self.opts is not None:
-            failargs_limit = self.opts.failargs_limit
-        else:
-            failargs_limit = 1000
-        self.assembler = Assembler386(self, self.translate_support_code,
-                                            failargs_limit)
-
-    def get_on_leave_jitted_hook(self):
-        return self.assembler.leave_jitted_hook
+        self.assembler = Assembler386(self, self.translate_support_code)
 
     def setup_once(self):
         self.profile_agent.startup()
@@ -118,7 +110,7 @@
         return self.assembler.fail_ebp
 
     def make_execute_token(self, *ARGS):
-        FUNCPTR = lltype.Ptr(lltype.FuncType(ARGS, lltype.Signed))
+        FUNCPTR = lltype.Ptr(lltype.FuncType(ARGS, llmemory.GCREF))
         #
         def execute_token(executable_token, *args):
             clt = executable_token.compiled_loop_token
@@ -132,12 +124,12 @@
                 prev_interpreter = LLInterpreter.current_interpreter
                 LLInterpreter.current_interpreter = self.debug_ll_interpreter
             try:
-                fail_index = func(*args)
+                deadframe = func(*args)
             finally:
                 if not self.translate_support_code:
                     LLInterpreter.current_interpreter = prev_interpreter
             #llop.debug_print(lltype.Void, "<<<< Back")
-            return self.get_fail_descr_from_number(fail_index)
+            return deadframe
         return execute_token
 
     def cast_ptr_to_int(x):
diff --git a/pypy/jit/backend/x86/support.py b/pypy/jit/backend/x86/support.py
--- a/pypy/jit/backend/x86/support.py
+++ b/pypy/jit/backend/x86/support.py
@@ -3,31 +3,6 @@
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
 from pypy.jit.backend.x86.arch import WORD
 
-
-def values_array(TP, size):
-    ATP = lltype.GcArray(TP)
-    
-    class ValuesArray(object):
-        SIZE = size
-
-        def __init__(self):
-            self.ar = lltype.malloc(ATP, size, zero=True, immortal=True)
-
-        def get_addr_for_num(self, i):
-            return rffi.cast(lltype.Signed, lltype.direct_ptradd(
-                lltype.direct_arrayitems(self.ar), i))
-
-        def setitem(self, i, v):
-            self.ar[i] = v
-
-        def getitem(self, i):
-            return self.ar[i]
-
-        def _freeze_(self):
-            return True
-
-    return ValuesArray()
-
 # ____________________________________________________________
 
 memcpy_fn = rffi.llexternal('memcpy', [llmemory.Address, llmemory.Address,
diff --git a/pypy/jit/metainterp/history.py b/pypy/jit/metainterp/history.py
--- a/pypy/jit/metainterp/history.py
+++ b/pypy/jit/metainterp/history.py
@@ -137,8 +137,10 @@
     def same_box(self, other):
         return self is other
 
+
 class AbstractDescr(AbstractValue):
     __slots__ = ()
+    llopaque = True
 
     def repr_of_descr(self):
         return '%r' % (self,)
@@ -151,6 +153,17 @@
             assert clone.__class__ is self.__class__
         return clone
 
+    def hide(self, cpu):
+        descr_ptr = cpu.ts.cast_instance_to_base_ref(self)
+        return cpu.ts.cast_to_ref(descr_ptr)
+
+    @staticmethod
+    def show(cpu, descr_gcref):
+        from pypy.rpython.annlowlevel import cast_base_ptr_to_instance
+        descr_ptr = cpu.ts.cast_to_baseclass(descr_gcref)
+        return cast_base_ptr_to_instance(AbstractDescr, descr_ptr)
+
+
 class AbstractFailDescr(AbstractDescr):
     index = -1
 
diff --git a/pypy/rlib/rerased.py b/pypy/rlib/rerased.py
--- a/pypy/rlib/rerased.py
+++ b/pypy/rlib/rerased.py
@@ -130,6 +130,7 @@
 # ---------- implementation-specific ----------
 
 class Erased(object):
+    _TYPE = llmemory.GCREF
     def __init__(self, x, identity):
         self._x = x
         self._identity = identity
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to