Author: Remi Meier <[email protected]>
Branch: stmgc-c8-gcc
Changeset: r79670:9ca388f9503e
Date: 2015-09-17 17:58 +0200
http://bitbucket.org/pypy/pypy/changeset/9ca388f9503e/

Log:    The problem in the previous commit seems to be that
        INVALID_CACHE_ENTRY is prebuilt. It is enough to make it not
        prebuilt to pass the test. Painfully adapt code in mapdict.py to
        make sure its not prebuilt...

diff --git a/pypy/objspace/std/mapdict.py b/pypy/objspace/std/mapdict.py
--- a/pypy/objspace/std/mapdict.py
+++ b/pypy/objspace/std/mapdict.py
@@ -837,36 +837,53 @@
                 return True
         return False
 
-_invalid_cache_entry_map = objectmodel.instantiate(AbstractAttribute)
-_invalid_cache_entry_map.terminator = None
-INVALID_CACHE_ENTRY = CacheEntry()
-INVALID_CACHE_ENTRY.map_wref = weakref.ref(_invalid_cache_entry_map)
+    def _cleanup_(self):
+        raise Exception("cannot translate a prebuilt CacheEntry") # for 
unknown reasons
+
+# _invalid_cache_entry_map = objectmodel.instantiate(AbstractAttribute)
+# _invalid_cache_entry_map.terminator = None
+# INVALID_CACHE_ENTRY = CacheEntry()
+# INVALID_CACHE_ENTRY.map_wref = weakref.ref(_invalid_cache_entry_map)
                                  # different from any real map ^^^
 
 from rpython.rtyper.lltypesystem import lltype, llmemory
 from rpython.rtyper import annlowlevel
 MAPDICT_CACHE = lltype.GcArray(llmemory.GCREF)
-PMAPDICT_CACHE = lltype.Ptr(MAPDICT_CACHE)
 NULL_MAPDICTCACHE = lltype.nullptr(MAPDICT_CACHE)
 
+def init_mapdict_cache(pycode):
+    # pycode._mapdict_caches = [INVALID_CACHE_ENTRY] * num_entries
+    pycode._mapdict_caches = NULL_MAPDICTCACHE
 
-def init_mapdict_cache(pycode):
+def lazy_init_mapdict_cache(pycode):
+    assert we_are_translated()
     num_entries = len(pycode.co_names_w)
-    # pycode._mapdict_caches = [INVALID_CACHE_ENTRY] * num_entries
     if pycode.space.config.translation.stm:
         from rpython.rlib.rstm import allocate_noconflict
         pycode._mapdict_caches = allocate_noconflict(MAPDICT_CACHE, 
num_entries)
     else:
         pycode._mapdict_caches = lltype.malloc(MAPDICT_CACHE, num_entries)
     #
+    # create invalid entry (should be prebuilt, but then translation fails)
+    _invalid_cache_entry_map = objectmodel.instantiate(AbstractAttribute)
+    _invalid_cache_entry_map.terminator = None
+    pycode._mapdict_cache_invalid = CacheEntry()
+    pycode._mapdict_cache_invalid.map_wref = 
weakref.ref(_invalid_cache_entry_map)
+    #                                   different from any real map ^^^
+    #
     for i in range(num_entries):
-        pycode._mapdict_caches[i] = 
annlowlevel.cast_instance_to_gcref(INVALID_CACHE_ENTRY)
+        pycode._mapdict_caches[i] = 
annlowlevel.cast_instance_to_gcref(pycode._mapdict_cache_invalid)
 
 
 @jit.dont_look_inside
 def _fill_cache(pycode, nameindex, map, version_tag, storageindex, 
w_method=None):
+    if not we_are_translated():
+        return
+    if pycode._mapdict_caches is NULL_MAPDICTCACHE:
+        lazy_init_mapdict_cache(pycode)
+    #
     entry = annlowlevel.cast_gcref_to_instance(CacheEntry, 
pycode._mapdict_caches[nameindex])
-    if entry is INVALID_CACHE_ENTRY:
+    if entry is pycode._mapdict_cache_invalid:
         entry = CacheEntry()
         pycode._mapdict_caches[nameindex] = 
annlowlevel.cast_instance_to_gcref(entry)
     entry.map_wref = weakref.ref(map)
@@ -879,6 +896,11 @@
 def LOAD_ATTR_caching(pycode, w_obj, nameindex):
     # this whole mess is to make the interpreter quite a bit faster; it's not
     # used if we_are_jitted().
+    if not we_are_translated():
+        return LOAD_ATTR_slowpath(pycode, w_obj, nameindex, 
w_obj._get_mapdict_map())
+    if pycode._mapdict_caches is NULL_MAPDICTCACHE:
+        lazy_init_mapdict_cache(pycode)
+    #
     entry = annlowlevel.cast_gcref_to_instance(CacheEntry, 
pycode._mapdict_caches[nameindex])
     map = w_obj._get_mapdict_map()
     if entry.is_valid_for_map(map) and entry.w_method is None:
@@ -930,12 +952,17 @@
                     _fill_cache(pycode, nameindex, map, version_tag, 
attr.storageindex)
                     return w_obj._mapdict_read_storage(attr.storageindex)
     if space.config.objspace.std.withmethodcachecounter:
-        INVALID_CACHE_ENTRY.failure_counter += 1
+        pycode._mapdict_cache_invalid.failure_counter += 1
     return space.getattr(w_obj, w_name)
 LOAD_ATTR_slowpath._dont_inline_ = True
 
 def LOOKUP_METHOD_mapdict(f, nameindex, w_obj):
     pycode = f.getcode()
+    if not we_are_translated():
+        return False
+    if pycode._mapdict_caches is NULL_MAPDICTCACHE:
+        lazy_init_mapdict_cache(pycode)
+    #
     entry = annlowlevel.cast_gcref_to_instance(CacheEntry, 
pycode._mapdict_caches[nameindex])
     if entry.is_valid_for_obj(w_obj):
         w_method = entry.w_method
diff --git a/pypy/objspace/std/test/test_mapdict.py 
b/pypy/objspace/std/test/test_mapdict.py
--- a/pypy/objspace/std/test/test_mapdict.py
+++ b/pypy/objspace/std/test/test_mapdict.py
@@ -719,21 +719,25 @@
         def check(space, w_func, name):
             w_code = space.getattr(w_func, space.wrap('func_code'))
             nameindex = map(space.str_w, w_code.co_names_w).index(name)
+            if not w_code._mapdict_caches:# is NULL_MAPDICTCACHE:
+                lazy_init_mapdict_cache(w_code)
+            #
             entry = annlowlevel.cast_gcref_to_instance(CacheEntry, 
w_code._mapdict_caches[nameindex])
             entry.failure_counter = 0
             entry.success_counter = 0
-            INVALID_CACHE_ENTRY.failure_counter = 0
+            # INVALID_CACHE_ENTRY.failure_counter = 0
+            w_code._mapdict_cache_invalid.failure_counter = 0
             #
             w_res = space.call_function(w_func)
             assert space.eq_w(w_res, space.wrap(42))
             #
             entry = annlowlevel.cast_gcref_to_instance(CacheEntry, 
w_code._mapdict_caches[nameindex])
-            if entry is INVALID_CACHE_ENTRY:
+            if entry is w_code._mapdict_cache_invalid:
                 failures = successes = 0
             else:
                 failures = entry.failure_counter
                 successes = entry.success_counter
-            globalfailures = INVALID_CACHE_ENTRY.failure_counter
+            globalfailures = w_code._mapdict_cache_invalid.failure_counter
             return space.wrap((failures, successes, globalfailures))
         check.unwrap_spec = [gateway.ObjSpace, gateway.W_Root, str]
         cls.w_check = cls.space.wrap(gateway.interp2app(check))
diff --git a/rpython/translator/stm/test/test_ztranslated.py 
b/rpython/translator/stm/test/test_ztranslated.py
--- a/rpython/translator/stm/test/test_ztranslated.py
+++ b/rpython/translator/stm/test/test_ztranslated.py
@@ -741,18 +741,27 @@
 
     def test_allocate_noconflict3(self):
         MAPDICT_CACHE = lltype.GcArray(llmemory.GCREF)
+        NULL_MAPDICTCACHE = lltype.nullptr(MAPDICT_CACHE)
 
         class CacheEntry(object): pass
-        INVALID_CACHE_ENTRY = CacheEntry()
+        # INVALID_CACHE_ENTRY = CacheEntry()
 
         class P(): pass
         pbc = P()
-        pbc.cache = rstm.allocate_noconflict(MAPDICT_CACHE, 5)
-        for i in range(5):
-            pbc.cache[i] = cast_instance_to_gcref(INVALID_CACHE_ENTRY)
+        pbc.cache = NULL_MAPDICTCACHE
+
+        def init():
+            pbc.cache = rstm.allocate_noconflict(MAPDICT_CACHE, 5)
+            for i in range(5):
+                pbc.cache[i] = cast_instance_to_gcref(pbc.invalid)
+
+        pbc.init = init
 
         def main(argv):
-            assert cast_gcref_to_instance(CacheEntry, pbc.cache[1]) is 
INVALID_CACHE_ENTRY
+            if pbc.cache is NULL_MAPDICTCACHE:
+                pbc.invalid = CacheEntry()
+                pbc.init()
+            assert cast_gcref_to_instance(CacheEntry, pbc.cache[1]) is 
pbc.invalid
             #
             print "ok!"
             return 0
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to