[pypy-svn] r65254 - in pypy/branch/pyjitpl5/pypy/jit/backend/x86: . test

arigo at codespeak.net arigo at codespeak.net
Tue May 12 21:06:02 CEST 2009


Author: arigo
Date: Tue May 12 21:06:00 2009
New Revision: 65254

Modified:
   pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py
   pypy/branch/pyjitpl5/pypy/jit/backend/x86/gc.py
   pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_zrpy_gc.py
Log:
Add the class GcRefList, designed to help with putting references
to GC objects in the assembler.


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	Tue May 12 21:06:00 2009
@@ -146,6 +146,12 @@
             # the address of the function called by 'new'
             ll_new = self.cpu.gc_ll_descr.get_funcptr_for_new()
             self.malloc_func_addr = rffi.cast(lltype.Signed, ll_new)
+            # for moving GCs, the array used to hold the address of GC objects
+            # that appear as ConstPtr.
+            if self.cpu.gc_ll_descr.moving_gc:
+                self.gcrefs = self.cpu.gc_ll_descr.GcRefList()
+            else:
+                self.gcrefs = None
 
     def eventually_log_operations(self, inputargs, operations, memo=None,
                                   myid=0):

Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/gc.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/x86/gc.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/gc.py	Tue May 12 21:06:00 2009
@@ -1,3 +1,4 @@
+from pypy.rlib import rgc
 from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rclass
 from pypy.rpython.lltypesystem.lloperation import llop
 from pypy.rpython.annlowlevel import llhelper
@@ -5,6 +6,7 @@
 from pypy.jit.backend.x86 import symbolic
 from pypy.jit.backend.x86.runner import ConstDescr3
 
+# ____________________________________________________________
 
 class GcLLDescription:
     def __init__(self, gcdescr, mixlevelann):
@@ -15,6 +17,7 @@
 # ____________________________________________________________
 
 class GcLLDescr_boehm(GcLLDescription):
+    moving_gc = False
 
     def __init__(self, gcdescr, mixlevelann):
         # grab a pointer to the Boehm 'malloc' function
@@ -53,7 +56,69 @@
 
 # ____________________________________________________________
 
+class GcRefList:
+    """Handles all references from the generated assembler to GC objects.
+    This is implemented as a nonmovable, but GC, list; the assembler contains
+    code that will (for now) always read from this list."""
+
+    GCREF_LIST = lltype.GcArray(llmemory.GCREF)     # followed by the GC
+
+    HASHTABLE = rffi.CArray(llmemory.Address)      # ignored by the GC
+    HASHTABLE_BITS = 10
+    HASHTABLE_SIZE = 1 << HASHTABLE_BITS
+
+    def __init__(self):
+        self.list = self.alloc_gcref_list(2000)
+        self.nextindex = 0
+        self.oldlists = []
+        # A pseudo dictionary: it is fixed size, and it may contain
+        # random nonsense after a collection moved the objects.  It is only
+        # used to avoid too many duplications in the GCREF_LISTs.
+        self.hashtable = lltype.malloc(self.HASHTABLE,
+                                       self.HASHTABLE_SIZE+1,
+                                       flavor='raw')
+        dummy = llmemory.itemoffsetof(self.hashtable, self.HASHTABLE_SIZE)
+        for i in range(self.HASHTABLE_SIZE+1):
+            self.hashtable[i] = dummy
+
+    def alloc_gcref_list(self, n):
+        # Important: the GRREF_LISTs allocated are *non-movable*.  This
+        # requires support in the gc (only the hybrid GC supports it so far).
+        list = rgc.malloc_nonmovable(self.GCREF_LIST, n)
+        assert list, "malloc_nonmovable failed!"
+        return list
+
+    def get_address_of_gcref(self, gcref):
+        assert lltype.typeOf(gcref) == llmemory.GCREF
+        # first look in the hashtable, using an inexact hash (fails after
+        # the object moves)
+        addr = llmemory.cast_ptr_to_adr(gcref)
+        hash = llmemory.cast_adr_to_int(addr)
+        hash -= hash >> self.HASHTABLE_BITS
+        hash &= self.HASHTABLE_SIZE - 1
+        addr_ref = self.hashtable[hash]
+        # the following test is safe anyway, because the addresses found
+        # in the hashtable are always the addresses of nonmovable stuff:
+        if addr_ref.address[0] == addr:
+            return addr_ref
+        # if it fails, add an entry to the list
+        if self.nextindex == len(self.list):
+            # reallocate first, increasing a bit the size every time
+            self.oldlists.append(self.list)
+            self.list = self.alloc_gcref_list(len(self.list) // 4 * 5)
+            self.nextindex = 0
+        # add it
+        index = self.nextindex
+        self.list[index] = gcref
+        addr_ref = llmemory.itemoffsetof(self.GCREF_LIST, index)
+        self.nextindex = index + 1
+        # record it in the hashtable
+        self.hashtable[hash] = addr_ref
+        return addr_ref
+
+
 class GcLLDescr_framework(GcLLDescription):
+    GcRefList = GcRefList
 
     def __init__(self, gcdescr, mixlevelann):
         from pypy.rpython.memory.gc.base import choose_gc_from_config
@@ -64,7 +129,8 @@
         # where it can be fished and reused by the FrameworkGCTransformer
         self.layoutbuilder = framework.TransformerLayoutBuilder()
         self.translator._transformerlayoutbuilder_from_jit = self.layoutbuilder
-        #GCClass, _ = choose_gc_from_config(gcdescr.config)
+        GCClass, _ = choose_gc_from_config(gcdescr.config)
+        self.moving_gc = GCClass.moving_gc
 
         # make a malloc function, with three arguments
         def malloc_basic(size, type_id, has_finalizer):

Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_zrpy_gc.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_zrpy_gc.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_zrpy_gc.py	Tue May 12 21:06:00 2009
@@ -5,6 +5,7 @@
 soon as possible (at least in a simple case).
 """
 import weakref
+import py
 from pypy.rlib import rgc
 from pypy.rpython.lltypesystem.lloperation import llop
 from pypy.rlib.jit import JitDriver
@@ -77,6 +78,7 @@
 def test_compile_boehm():
     compile_and_run("boehm")
 
-def test_compile_semispace():
-    # a moving GC, but with no write barrier
-    compile_and_run("semispace", gcrootfinder="asmgcc")
+def test_compile_hybrid():
+    py.test.skip("in-progress")
+    # a moving GC, with a write barrier.  Supports malloc_varsize_nonmovable.
+    compile_and_run("hybrid", gcrootfinder="asmgcc")



More information about the Pypy-commit mailing list