PageRenderTime 26ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/pypy/translator/test/test_stackcheck.py

https://bitbucket.org/pypy/pypy/
Python | 120 lines | 104 code | 15 blank | 1 comment | 19 complexity | 22d3313aa0bff165d208ea9bc1bf44ed MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. from pypy import conftest
  2. from pypy.translator.translator import TranslationContext, graphof
  3. from pypy.translator.backendopt.all import backend_optimizations
  4. from pypy.translator.transform import insert_ll_stackcheck
  5. from pypy.rpython.memory.gctransform import framework
  6. def _follow_path_naive(block, cur_path, accum):
  7. cur_path = (cur_path, block)
  8. if not block.exits:
  9. ops = []
  10. while cur_path:
  11. block = cur_path[1]
  12. ops.extend(reversed(block.operations))
  13. cur_path = cur_path[0]
  14. accum.append(list(reversed(ops)))
  15. return
  16. for link in block.exits:
  17. _follow_path_naive(link.target, cur_path, accum)
  18. # explodes on loops!
  19. def paths_naive(g):
  20. accum = []
  21. _follow_path_naive(g.startblock, None, accum)
  22. return accum
  23. def direct_target(spaceop):
  24. return spaceop.args[0].value._obj.graph.name
  25. def direct_calls(p):
  26. names = []
  27. for spaceop in p:
  28. if spaceop.opname == 'direct_call':
  29. names.append(direct_target(spaceop))
  30. return names
  31. def check(g, funcname, ignore=None):
  32. paths = paths_naive(g)
  33. relevant = []
  34. for p in paths:
  35. funcs_called = direct_calls(p)
  36. if funcname in funcs_called and ignore not in funcs_called:
  37. assert 'stack_check___' in funcs_called
  38. assert (funcs_called.index(funcname) >
  39. funcs_called.index('stack_check___'))
  40. relevant.append(p)
  41. return relevant
  42. class A(object):
  43. def __init__(self, n):
  44. self.n = n
  45. def f(a):
  46. x = A(a.n+1)
  47. if x.n == 10:
  48. return
  49. f(x)
  50. def g(n):
  51. f(A(n))
  52. return 0
  53. def test_simple():
  54. t = TranslationContext()
  55. a = t.buildannotator()
  56. a.build_types(g, [int])
  57. a.simplify()
  58. t.buildrtyper().specialize()
  59. backend_optimizations(t)
  60. t.checkgraphs()
  61. n = insert_ll_stackcheck(t)
  62. t.checkgraphs()
  63. assert n == 1
  64. if conftest.option.view:
  65. t.view()
  66. check(graphof(t, f), 'f')
  67. def test_gctransformed():
  68. t = TranslationContext()
  69. a = t.buildannotator()
  70. a.build_types(g, [int])
  71. a.simplify()
  72. t.buildrtyper().specialize()
  73. backend_optimizations(t)
  74. t.checkgraphs()
  75. n = insert_ll_stackcheck(t)
  76. t.checkgraphs()
  77. assert n == 1
  78. exctransf = t.getexceptiontransformer()
  79. f_graph = graphof(t, f)
  80. exctransf.create_exception_handling(f_graph)
  81. if conftest.option.view:
  82. f_graph.show()
  83. check(f_graph, 'f')
  84. class GCTransform(framework.FrameworkGCTransformer):
  85. from pypy.rpython.memory.gc.generation import GenerationGC as \
  86. GCClass
  87. GC_PARAMS = {}
  88. gctransf = GCTransform(t)
  89. gctransf.transform_graph(f_graph)
  90. if conftest.option.view:
  91. f_graph.show()
  92. relevant = check(f_graph, 'f')
  93. for p in relevant:
  94. in_between = False
  95. reload = 0
  96. for spaceop in p:
  97. if spaceop.opname == 'direct_call':
  98. target = direct_target(spaceop)
  99. if target == 'f':
  100. in_between = False
  101. elif target == 'stack_check___':
  102. in_between = True
  103. if in_between and spaceop.opname == 'gc_reload_possibly_moved':
  104. reload += 1
  105. assert reload == 0