PageRenderTime 57ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

/pypy/translator/c/gcc/test/test_trackgcroot.py

https://bitbucket.org/yrttyr/pypy
Python | 177 lines | 171 code | 6 blank | 0 comment | 0 complexity | 99268b7c2441ecb3156d8b26dbcfc240 MD5 | raw file
  1. import py
  2. import sys, re
  3. from pypy.translator.c.gcc.trackgcroot import LOC_NOWHERE, LOC_REG
  4. from pypy.translator.c.gcc.trackgcroot import LOC_EBP_PLUS, LOC_EBP_MINUS
  5. from pypy.translator.c.gcc.trackgcroot import LOC_ESP_PLUS
  6. from pypy.translator.c.gcc.trackgcroot import ElfAssemblerParser
  7. from pypy.translator.c.gcc.trackgcroot import DarwinAssemblerParser
  8. from pypy.translator.c.gcc.trackgcroot import PARSERS
  9. from pypy.translator.c.gcc.trackgcroot import ElfFunctionGcRootTracker32
  10. from StringIO import StringIO
  11. import py.test
  12. this_dir = py.path.local(__file__).dirpath()
  13. def test_format_location():
  14. cls = ElfFunctionGcRootTracker32
  15. assert cls.format_location(LOC_NOWHERE) == '?'
  16. assert cls.format_location(LOC_REG | (1<<2)) == '%ebx'
  17. assert cls.format_location(LOC_REG | (2<<2)) == '%esi'
  18. assert cls.format_location(LOC_REG | (3<<2)) == '%edi'
  19. assert cls.format_location(LOC_REG | (4<<2)) == '%ebp'
  20. assert cls.format_location(LOC_EBP_PLUS + 0) == '(%ebp)'
  21. assert cls.format_location(LOC_EBP_PLUS + 4) == '4(%ebp)'
  22. assert cls.format_location(LOC_EBP_MINUS + 4) == '-4(%ebp)'
  23. assert cls.format_location(LOC_ESP_PLUS + 0) == '(%esp)'
  24. assert cls.format_location(LOC_ESP_PLUS + 4) == '4(%esp)'
  25. def test_format_callshape():
  26. cls = ElfFunctionGcRootTracker32
  27. expected = ('{4(%ebp) ' # position of the return address
  28. '| 8(%ebp), 12(%ebp), 16(%ebp), 20(%ebp) ' # 4 saved regs
  29. '| 24(%ebp), 28(%ebp)}') # GC roots
  30. assert cls.format_callshape((LOC_EBP_PLUS+4,
  31. LOC_EBP_PLUS+8,
  32. LOC_EBP_PLUS+12,
  33. LOC_EBP_PLUS+16,
  34. LOC_EBP_PLUS+20,
  35. LOC_EBP_PLUS+24,
  36. LOC_EBP_PLUS+28)) == expected
  37. def test_compress_callshape():
  38. cls = ElfFunctionGcRootTracker32
  39. shape = (1, 127, 0x1234, 0x5678, 0x234567,
  40. 0x765432, 0x61626364, 0x41424344)
  41. bytes = list(cls.compress_callshape(shape))
  42. print bytes
  43. assert len(bytes) == 1+1+2+3+4+4+5+5+1
  44. assert cls.decompress_callshape(bytes) == list(shape)
  45. def test_find_functions_elf():
  46. source = """\
  47. \t.p2align 4,,15
  48. .globl pypy_g_make_tree
  49. \t.type\tpypy_g_make_tree, @function
  50. \tFOO
  51. \t.size\tpypy_g_make_tree, .-pypy_g_make_tree
  52. \t.p2align 4,,15
  53. .globl pypy_fn2
  54. \t.type\tpypy_fn2, @function
  55. \tBAR
  56. \t.size\tpypy_fn2, .-pypy_fn2
  57. \tMORE STUFF
  58. """
  59. lines = source.splitlines(True)
  60. parts = list(ElfAssemblerParser().find_functions(iter(lines)))
  61. assert len(parts) == 5
  62. assert parts[0] == (False, lines[:2])
  63. assert parts[1] == (True, lines[2:5])
  64. assert parts[2] == (False, lines[5:8])
  65. assert parts[3] == (True, lines[8:11])
  66. assert parts[4] == (False, lines[11:])
  67. def test_find_functions_darwin():
  68. source = """\
  69. \t.text
  70. \t.align 4,0x90
  71. .globl _pypy_g_ll_str__StringR_Ptr_GcStruct_rpy_strin_rpy_strin
  72. _pypy_g_ll_str__StringR_Ptr_GcStruct_rpy_strin_rpy_strin:
  73. L0:
  74. \tFOO
  75. \t.align 4,0x90
  76. _static:
  77. \tSTATIC
  78. \t.align 4,0x90
  79. .globl _pypy_g_ll_issubclass__object_vtablePtr_object_vtablePtr
  80. _pypy_g_ll_issubclass__object_vtablePtr_object_vtablePtr:
  81. \tBAR
  82. \t.cstring
  83. \t.ascii "foo"
  84. \t.text
  85. \t.align 4,0x90
  86. .globl _pypy_g_RPyRaiseException
  87. _pypy_g_RPyRaiseException:
  88. \tBAZ
  89. \t.section stuff
  90. """
  91. lines = source.splitlines(True)
  92. parts = list(DarwinAssemblerParser().find_functions(iter(lines)))
  93. assert len(parts) == 6
  94. assert parts[0] == (False, lines[:3])
  95. assert parts[1] == (True, lines[3:7])
  96. assert parts[2] == (True, lines[7:11])
  97. assert parts[3] == (True, lines[11:18])
  98. assert parts[4] == (True, lines[18:20])
  99. assert parts[5] == (False, lines[20:])
  100. def test_computegcmaptable():
  101. tests = []
  102. for format in ('elf', 'elf64', 'darwin', 'darwin64', 'msvc'):
  103. for path in this_dir.join(format).listdir("track*.s"):
  104. n = path.purebasename[5:]
  105. try:
  106. n = int(n)
  107. except ValueError:
  108. pass
  109. tests.append((format, n, path))
  110. tests.sort()
  111. for format, _, path in tests:
  112. yield check_computegcmaptable, format, path
  113. r_expected = re.compile(r"\s*;;\s*expected\s+([{].+[}])")
  114. r_gcroot_constant = re.compile(r";\tmov\t.+, .+_constant_always_one_")
  115. def check_computegcmaptable(format, path):
  116. if format == 'msvc':
  117. r_globallabel = re.compile(r"([\w]+)::")
  118. else:
  119. r_globallabel = re.compile(r"([\w]+)=[.]+")
  120. print
  121. print path.dirpath().basename + '/' + path.basename
  122. lines = path.readlines()
  123. expectedlines = lines[:]
  124. tracker = PARSERS[format].FunctionGcRootTracker(lines)
  125. table = tracker.computegcmaptable(verbose=sys.maxint)
  126. tabledict = {}
  127. seen = {}
  128. for entry in table:
  129. print '%s: %s' % (entry[0], tracker.format_callshape(entry[1]))
  130. tabledict[entry[0]] = entry[1]
  131. # find the ";; expected" lines
  132. prevline = ""
  133. for i, line in enumerate(lines):
  134. match = r_expected.match(line)
  135. if match:
  136. expected = match.group(1)
  137. prevmatch = r_globallabel.match(prevline)
  138. assert prevmatch, "the computed table is not complete"
  139. label = prevmatch.group(1)
  140. assert label in tabledict
  141. got = tabledict[label]
  142. assert tracker.format_callshape(got) == expected
  143. seen[label] = True
  144. if format == 'msvc':
  145. expectedlines.insert(i-2, 'PUBLIC\t%s\n' % (label,))
  146. expectedlines.insert(i-1, '%s::\n' % (label,))
  147. else:
  148. expectedlines.insert(i-2, '\t.globl\t%s\n' % (label,))
  149. expectedlines.insert(i-1, '%s=.+%d\n' % (label,
  150. tracker.OFFSET_LABELS))
  151. if format == 'msvc' and r_gcroot_constant.match(line):
  152. expectedlines[i] = ';' + expectedlines[i]
  153. expectedlines[i+1] = (expectedlines[i+1]
  154. .replace('\timul\t', '\tmov\t')
  155. + '\t; GCROOT\n')
  156. prevline = line
  157. assert len(seen) == len(tabledict), (
  158. "computed table contains unexpected entries:\n%r" %
  159. [key for key in tabledict if key not in seen])
  160. print '--------------- got ---------------'
  161. print ''.join(lines)
  162. print '------------- expected ------------'
  163. print ''.join(expectedlines)
  164. print '-----------------------------------'
  165. assert lines == expectedlines