Author: Armin Rigo <[email protected]>
Branch: gc_no_cleanup_nursery
Changeset: r73667:bade4d08b1c3
Date: 2014-09-23 16:09 +0200
http://bitbucket.org/pypy/pypy/changeset/bade4d08b1c3/

Log:    Test and fix: we need to explicitly zero the hash field in the
        assembler produced by NEWSTR or NEWUNICODE.

diff --git a/rpython/jit/backend/llsupport/gc.py 
b/rpython/jit/backend/llsupport/gc.py
--- a/rpython/jit/backend/llsupport/gc.py
+++ b/rpython/jit/backend/llsupport/gc.py
@@ -38,6 +38,8 @@
     def _setup_str(self):
         self.str_descr     = get_array_descr(self, rstr.STR)
         self.unicode_descr = get_array_descr(self, rstr.UNICODE)
+        self.str_hash_descr     = get_field_descr(self, rstr.STR,     'hash')
+        self.unicode_hash_descr = get_field_descr(self, rstr.UNICODE, 'hash')
 
     def generate_function(self, funcname, func, ARGS, RESULT=llmemory.GCREF):
         """Generates a variant of malloc with the given name and the given
diff --git a/rpython/jit/backend/llsupport/rewrite.py 
b/rpython/jit/backend/llsupport/rewrite.py
--- a/rpython/jit/backend/llsupport/rewrite.py
+++ b/rpython/jit/backend/llsupport/rewrite.py
@@ -147,14 +147,25 @@
         except KeyError:
             pass
 
-    def clear_varsize_gc_fields(self, descr, result, v_length=None):
+    def clear_varsize_gc_fields(self, kind, descr, result, v_length):
         if self.gc_ll_descr.malloc_zero_filled:
             return
-        if descr.is_array_of_structs() or descr.is_array_of_pointers():
-            # for the case of array of structs, this is for correctness only,
-            # since in practice all GC arrays of structs are allocated
-            # with malloc(zero=True)
-            self.handle_clear_array_contents(descr, result, v_length)
+        if kind == FLAG_ARRAY:
+            if descr.is_array_of_structs() or descr.is_array_of_pointers():
+                # for the case of array of structs, this is for correctness
+                # only, since in practice all GC arrays of structs are
+                # allocated with malloc(zero=True)
+                self.handle_clear_array_contents(descr, result, v_length)
+            return
+        if kind == FLAG_STR:
+            hash_descr = self.gc_ll_descr.str_hash_descr
+        elif kind == FLAG_UNICODE:
+            hash_descr = self.gc_ll_descr.unicode_hash_descr
+        else:
+            return
+        op = ResOperation(rop.SETFIELD_GC, [result, self.c_zero], None,
+                          descr=hash_descr)
+        self.newops.append(op)
 
     def handle_new_fixedsize(self, descr, op):
         assert isinstance(descr, SizeDescr)
@@ -185,8 +196,8 @@
             # might end up being allocated by malloc_external or some
             # stuff that initializes GC header fields differently
             self.gen_initialize_len(op.result, v_length, arraydescr.lendescr)
-            if kind == FLAG_ARRAY:
-                self.clear_varsize_gc_fields(op.getdescr(), op.result, 
v_length)
+            self.clear_varsize_gc_fields(kind, op.getdescr(), op.result,
+                                         v_length)
             return
         if (total_size >= 0 and
                 self.gen_malloc_nursery(total_size, op.result)):
@@ -204,8 +215,7 @@
                 self.gen_malloc_unicode(v_length, op.result)
             else:
                 raise NotImplementedError(op.getopname())
-        if kind == FLAG_ARRAY:
-            self.clear_varsize_gc_fields(op.getdescr(), op.result, v_length)
+        self.clear_varsize_gc_fields(kind, op.getdescr(), op.result, v_length)
 
     def handle_clear_array_contents(self, arraydescr, v_arr, v_length=None):
         # XXX more work here to reduce or remove the ZERO_ARRAY in some cases
diff --git a/rpython/jit/backend/llsupport/test/test_rewrite.py 
b/rpython/jit/backend/llsupport/test/test_rewrite.py
--- a/rpython/jit/backend/llsupport/test/test_rewrite.py
+++ b/rpython/jit/backend/llsupport/test/test_rewrite.py
@@ -69,6 +69,8 @@
         unicodedescr = self.gc_ll_descr.unicode_descr
         strlendescr     = strdescr.lendescr
         unicodelendescr = unicodedescr.lendescr
+        strhashdescr     = self.gc_ll_descr.str_hash_descr
+        unicodehashdescr = self.gc_ll_descr.unicode_hash_descr
 
         casmdescr = JitCellToken()
         clt = FakeLoopToken()
@@ -427,6 +429,7 @@
         [i0]
         p0 = call_malloc_nursery_varsize(1, 1, i0, descr=strdescr)
         setfield_gc(p0, i0, descr=strlendescr)
+        setfield_gc(p0, 0, descr=strhashdescr)
         jump(i0)
         """)
 
@@ -550,15 +553,19 @@
                         unicodedescr.basesize + 10 * unicodedescr.itemsize)d)
             setfield_gc(p0, %(strdescr.tid)d, descr=tiddescr)
             setfield_gc(p0, 14, descr=strlendescr)
+            setfield_gc(p0, 0, descr=strhashdescr)
             p1 = int_add(p0, %(strdescr.basesize + 16 * strdescr.itemsize)d)
             setfield_gc(p1, %(unicodedescr.tid)d, descr=tiddescr)
             setfield_gc(p1, 10, descr=unicodelendescr)
+            setfield_gc(p1, 0, descr=unicodehashdescr)
             p2 = call_malloc_nursery_varsize(2, %(unicodedescr.itemsize)d, i2,\
                                 descr=unicodedescr)
             setfield_gc(p2, i2, descr=unicodelendescr)
+            setfield_gc(p2, 0, descr=unicodehashdescr)
             p3 = call_malloc_nursery_varsize(1, 1, i2, \
                                 descr=strdescr)
             setfield_gc(p3, i2, descr=strlendescr)
+            setfield_gc(p3, 0, descr=strhashdescr)
             jump()
         """)
 
@@ -764,6 +771,7 @@
             p1 = call_malloc_nursery_varsize(1, 1, i0, \
                                 descr=strdescr)
             setfield_gc(p1, i0, descr=strlendescr)
+            setfield_gc(p1, 0, descr=strhashdescr)
             cond_call_gc_wb(p0, descr=wbdescr)
             setfield_gc(p0, p1, descr=tzdescr)
             jump()
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to