Commits

Armin Rigo  committed 71db844

Yay! test_zrpy_gc passes.

  • Participants
  • Parent commits cd409b4
  • Branches remove-globals-in-jit

Comments (0)

Files changed (8)

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

 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
         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)
             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
 
     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

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

 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
 
         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)
 
         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)
 
                 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
 

File pypy/jit/metainterp/warmspot.py

             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(

File pypy/rpython/lltypesystem/lloperation.py

     '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 ----------
 

File pypy/rpython/lltypesystem/opimpl.py

 def op_gc_assume_young_pointers(addr):
     pass
 
+def op_gc_set_extra_threshold(threshold):
+    pass
+
 def op_shrink_array(array, smallersize):
     return False
 

File pypy/rpython/memory/gc/minimark.py

         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:
         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")
 
 
     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

File pypy/rpython/memory/gctransform/framework.py

             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,
                   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,

File pypy/translator/c/src/mem.h

 #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 */