[pypy-commit] pypy default: This kind of lltype.GcStruct, with many pointer fields to a similar type,

arigo noreply at buildbot.pypy.org
Tue Sep 22 22:21:57 CEST 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r79778:5925e55c154c
Date: 2015-09-22 22:22 +0200
http://bitbucket.org/pypy/pypy/changeset/5925e55c154c/

Log:	This kind of lltype.GcStruct, with many pointer fields to a similar
	type, could lead to a very deep stack causing stack overflows. Fix.

diff --git a/rpython/jit/backend/llsupport/descr.py b/rpython/jit/backend/llsupport/descr.py
--- a/rpython/jit/backend/llsupport/descr.py
+++ b/rpython/jit/backend/llsupport/descr.py
@@ -75,15 +75,16 @@
     except KeyError:
         size = symbolic.get_size(STRUCT, gccache.translate_support_code)
         immutable_flag = heaptracker.is_immutable_struct(STRUCT)
-        gc_fielddescrs = heaptracker.gc_fielddescrs(gccache, STRUCT)
         if vtable:
             assert heaptracker.has_gcstruct_a_vtable(STRUCT)
         else:
             assert not heaptracker.has_gcstruct_a_vtable(STRUCT)
-        sizedescr = SizeDescr(size, gc_fielddescrs, vtable=vtable,
+        sizedescr = SizeDescr(size, vtable=vtable,
                               immutable_flag=immutable_flag)
         gccache.init_size_descr(STRUCT, sizedescr)
         cache[STRUCT] = sizedescr
+        gc_fielddescrs = heaptracker.gc_fielddescrs(gccache, STRUCT)
+        sizedescr.gc_fielddescrs = gc_fielddescrs
         all_fielddescrs = heaptracker.all_fielddescrs(gccache, STRUCT)
         sizedescr.all_fielddescrs = all_fielddescrs
         return sizedescr
diff --git a/rpython/jit/backend/llsupport/test/test_descr.py b/rpython/jit/backend/llsupport/test/test_descr.py
--- a/rpython/jit/backend/llsupport/test/test_descr.py
+++ b/rpython/jit/backend/llsupport/test/test_descr.py
@@ -460,3 +460,12 @@
     descr = FieldDescr('descr', 0, 1, FLAG_SIGNED)
     assert descr.get_integer_min() == -128
     assert descr.get_integer_max() == 127
+
+
+def test_size_descr_stack_overflow_bug():
+    c0 = GcCache(False)
+    S = lltype.GcForwardReference()
+    P = lltype.Ptr(S)
+    fields = [('x%d' % i, P) for i in range(1500)]
+    S.become(lltype.GcStruct('S', *fields))
+    get_size_descr(c0, S)


More information about the pypy-commit mailing list