[pypy-commit] pypy remove-globals-in-jit: Yay! test_zrpy_gc passes.

arigo noreply at buildbot.pypy.org
Fri Nov 16 17:41:35 CET 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: remove-globals-in-jit
Changeset: r58959:71db8445fbb3
Date: 2012-11-16 17:41 +0100
http://bitbucket.org/pypy/pypy/changeset/71db8445fbb3/

Log:	Yay! test_zrpy_gc passes.

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
@@ -32,7 +32,7 @@
 from pypy.jit.metainterp.resoperation import rop, ResOperation
 from pypy.jit.backend.x86 import support
 from pypy.rlib.debug import (debug_print, debug_start, debug_stop,
-                             have_debug_prints)
+                             have_debug_prints, fatalerror)
 from pypy.rlib import rgc
 from pypy.rlib.clibffi import FFI_DEFAULT_ABI
 from pypy.jit.backend.x86.jump import remap_frame_layout
@@ -1958,11 +1958,9 @@
         return arglocs[:]
 
     @staticmethod
-    @rgc.no_collect
+    #@rgc.no_collect -- XXX still true, but hacked gc_set_extra_threshold
     def grab_frame_values(cpu, bytecode, frame_addr, allregisters):
-        # no malloc allowed here!! XXX we allocate anyway the deadframe.
-        # It will only work on Boehm.
-        assert cpu.gc_ll_descr.kind == "boehm", "XXX Boehm only"
+        # no malloc allowed here!!  xxx apart from one, hacking a lot
         #self.fail_ebp = allregisters[16 + ebp.value]
         num = 0
         deadframe = lltype.nullptr(jitframe.DEADFRAME)
@@ -1996,8 +1994,16 @@
             num += 1
         # allocate the deadframe
         if not deadframe:
+            # Remove the "reserve" at the end of the nursery.  This means
+            # that it is guaranteed that the following malloc() works
+            # without requiring a collect(), but it needs to be re-added
+            # as soon as possible.
+            cpu.gc_clear_extra_threshold()
             assert num <= cpu.get_failargs_limit()
-            deadframe = lltype.malloc(jitframe.DEADFRAME, num)
+            try:
+                deadframe = lltype.malloc(jitframe.DEADFRAME, num)
+            except MemoryError:
+                fatalerror("memory usage error in grab_frame_values")
         # fill it
         code_inputarg = False
         num = 0
@@ -2083,7 +2089,7 @@
 
     def setup_failure_recovery(self):
 
-        @rgc.no_collect
+        #@rgc.no_collect -- XXX still true, but hacked gc_set_extra_threshold
         def failure_recovery_func(registers):
             # 'registers' is a pointer to a structure containing the
             # original value of the registers, optionally the original
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
@@ -2,7 +2,7 @@
 from pypy.rpython.lltypesystem import lltype, llmemory, rffi
 from pypy.rpython.lltypesystem.lloperation import llop
 from pypy.rpython.llinterp import LLInterpreter
-from pypy.rlib.objectmodel import we_are_translated
+from pypy.rlib.objectmodel import we_are_translated, specialize
 from pypy.rlib.jit_hooks import LOOP_RUN_CONTAINER
 from pypy.jit.codewriter import longlong
 from pypy.jit.metainterp import history, compile
@@ -45,6 +45,10 @@
 
         self.profile_agent = profile_agent
 
+        from pypy.jit.backend.llsupport import jitframe
+        self.deadframe_size_max = llmemory.sizeof(jitframe.DEADFRAME,
+                                                  self.get_failargs_limit())
+
     def set_debug(self, flag):
         return self.assembler.set_debug(flag)
 
@@ -54,6 +58,12 @@
         else:
             return 1000
 
+    def gc_set_extra_threshold(self):
+        llop.gc_set_extra_threshold(lltype.Void, self.deadframe_size_max)
+
+    def gc_clear_extra_threshold(self):
+        llop.gc_set_extra_threshold(lltype.Void, 0)
+
     def setup(self):
         self.assembler = Assembler386(self, self.translate_support_code)
 
@@ -119,6 +129,7 @@
                 if not self.translate_support_code:
                     LLInterpreter.current_interpreter = prev_interpreter
             #llop.debug_print(lltype.Void, "<<<< Back")
+            self.gc_set_extra_threshold()
             return deadframe
         return execute_token
 
diff --git a/pypy/jit/metainterp/warmspot.py b/pypy/jit/metainterp/warmspot.py
--- a/pypy/jit/metainterp/warmspot.py
+++ b/pypy/jit/metainterp/warmspot.py
@@ -888,8 +888,11 @@
             EffectInfo.MOST_GENERAL)
 
         vinfo = jd.virtualizable_info
+        gc_set_extra_threshold = getattr(self.cpu, 'gc_set_extra_threshold',
+                                         lambda: None)
 
         def assembler_call_helper(deadframe, virtualizableref):
+            gc_set_extra_threshold()    # XXX temporary hack
             fail_descr = self.cpu.get_latest_descr(deadframe)
             if vinfo is not None:
                 virtualizable = lltype.cast_opaque_ptr(
diff --git a/pypy/rpython/lltypesystem/lloperation.py b/pypy/rpython/lltypesystem/lloperation.py
--- a/pypy/rpython/lltypesystem/lloperation.py
+++ b/pypy/rpython/lltypesystem/lloperation.py
@@ -499,6 +499,7 @@
     'gc_typeids_z'        : LLOp(),
     'gc_gcflag_extra'     : LLOp(),
     'gc_add_memory_pressure': LLOp(),
+    'gc_set_extra_threshold': LLOp(canrun=True),
 
     # ------- JIT & GC interaction, only for some GCs ----------
 
diff --git a/pypy/rpython/lltypesystem/opimpl.py b/pypy/rpython/lltypesystem/opimpl.py
--- a/pypy/rpython/lltypesystem/opimpl.py
+++ b/pypy/rpython/lltypesystem/opimpl.py
@@ -644,6 +644,9 @@
 def op_gc_assume_young_pointers(addr):
     pass
 
+def op_gc_set_extra_threshold(threshold):
+    pass
+
 def op_shrink_array(array, smallersize):
     return False
 
diff --git a/pypy/rpython/memory/gc/minimark.py b/pypy/rpython/memory/gc/minimark.py
--- a/pypy/rpython/memory/gc/minimark.py
+++ b/pypy/rpython/memory/gc/minimark.py
@@ -250,6 +250,7 @@
         self.nursery_top  = NULL
         self.debug_tiny_nursery = -1
         self.debug_rotating_nurseries = None
+        self.extra_threshold = 0
         #
         # The ArenaCollection() handles the nonmovable objects allocation.
         if ArenaCollectionClass is None:
@@ -404,6 +405,7 @@
         self.next_major_collection_initial = self.min_heap_size
         self.next_major_collection_threshold = self.min_heap_size
         self.set_major_threshold_from(0.0)
+        ll_assert(self.extra_threshold == 0, "extra_threshold set too early")
         debug_stop("gc-set-nursery-size")
 
 
@@ -1817,6 +1819,19 @@
     def identityhash(self, gcobj):
         return self.id_or_identityhash(gcobj, True)
 
+    # ----------
+    # set_extra_threshold support
+
+    def set_extra_threshold(self, reserved_size):
+        ll_assert(reserved_size <= self.nonlarge_max,
+                  "set_extra_threshold: too big!")
+        diff = reserved_size - self.extra_threshold
+        if diff > 0 and self.nursery_free + diff > self.nursery_top:
+            self.minor_collection()
+        self.nursery_size -= diff
+        self.nursery_top -= diff
+        self.extra_threshold += diff
+
 
     # ----------
     # Finalizers
diff --git a/pypy/rpython/memory/gctransform/framework.py b/pypy/rpython/memory/gctransform/framework.py
--- a/pypy/rpython/memory/gctransform/framework.py
+++ b/pypy/rpython/memory/gctransform/framework.py
@@ -386,6 +386,10 @@
             self.obtainfreespace_ptr = getfn(GCClass.obtain_free_space.im_func,
                                              [s_gc, annmodel.SomeInteger()],
                                              annmodel.SomeAddress())
+        if getattr(GCClass, 'set_extra_threshold', False):
+            self.setextrathreshold_ptr = getfn(
+                GCClass.set_extra_threshold.im_func,
+                [s_gc, annmodel.SomeInteger()], annmodel.s_None)
 
         if GCClass.moving_gc:
             self.id_ptr = getfn(GCClass.id.im_func,
@@ -966,6 +970,13 @@
                   resultvar=hop.spaceop.result)
         self.pop_roots(hop, livevars)
 
+    def gct_gc_set_extra_threshold(self, hop):
+        livevars = self.push_roots(hop)
+        [v_size] = hop.spaceop.args
+        hop.genop("direct_call",
+                  [self.setextrathreshold_ptr, self.c_const_gc, v_size])
+        self.pop_roots(hop, livevars)
+
     def gct_gc_set_max_heap_size(self, hop):
         [v_size] = hop.spaceop.args
         hop.genop("direct_call", [self.set_max_heap_size_ptr,
diff --git a/pypy/translator/c/src/mem.h b/pypy/translator/c/src/mem.h
--- a/pypy/translator/c/src/mem.h
+++ b/pypy/translator/c/src/mem.h
@@ -253,3 +253,4 @@
 #define OP_GC_GET_RPY_TYPE_INDEX(x, r)   r = -1
 #define OP_GC_IS_RPY_INSTANCE(x, r)      r = 0
 #define OP_GC_DUMP_RPY_HEAP(fd, r)       r = 0
+#define OP_GC_SET_EXTRA_THRESHOLD(x, r)  /* nothing */


More information about the pypy-commit mailing list