PageRenderTime 49ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/rpython/jit/metainterp/test/test_counter.py

https://bitbucket.org/pypy/pypy/
Python | 130 lines | 109 code | 12 blank | 9 comment | 17 complexity | 1cbcc1d96a226d806e9493d06a045525 MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. from rpython.jit.metainterp.counter import JitCounter
  2. def test_get_index():
  3. jc = JitCounter(size=128) # 7 bits
  4. for i in range(10):
  5. hash = 400000001 * i
  6. index = jc._get_index(hash)
  7. assert index == (hash >> (32 - 7))
  8. def test_get_subhash():
  9. assert JitCounter._get_subhash(0x518ebd) == 0x8ebd
  10. def test_fetch_next_hash():
  11. jc = JitCounter(size=2048)
  12. # check the distribution of "fetch_next_hash() & ~7".
  13. blocks = [[jc.fetch_next_hash() & ~7 for i in range(65536)]
  14. for j in range(2)]
  15. for block in blocks:
  16. assert 0 <= jc._get_index(block[0]) < 2048
  17. assert 0 <= jc._get_index(block[-1]) < 2048
  18. assert 0 <= jc._get_index(block[2531]) < 2048
  19. assert 0 <= jc._get_index(block[45981]) < 2048
  20. # should be correctly distributed: ideally 2047 or 2048 different
  21. # values
  22. assert len(set([jc._get_index(x) for x in block])) >= 2040
  23. # check that the subkeys are distinct for same-block entries
  24. subkeys = {}
  25. for block in blocks:
  26. for x in block:
  27. idx = jc._get_index(x)
  28. subkeys.setdefault(idx, []).append(jc._get_subhash(x))
  29. collisions = 0
  30. for idx, sks in subkeys.items():
  31. collisions += len(sks) - len(set(sks))
  32. assert collisions < 5
  33. def index2hash(jc, index, subhash=0):
  34. assert 0 <= subhash < 65536
  35. return (index << jc.shift) | subhash
  36. def test_tick():
  37. jc = JitCounter()
  38. jc._tick_slowpath = "not callable in this test!"
  39. incr = jc.compute_threshold(4)
  40. for i in range(5):
  41. r = jc.tick(index2hash(jc, 104), incr)
  42. assert r is (i == 3)
  43. for i in range(5):
  44. r = jc.tick(index2hash(jc, 108), incr)
  45. s = jc.tick(index2hash(jc, 109), incr)
  46. assert r is (i == 3)
  47. assert s is (i == 3)
  48. jc.reset(index2hash(jc, 108))
  49. for i in range(5):
  50. r = jc.tick(index2hash(jc, 108), incr)
  51. assert r is (i == 3)
  52. def test_collisions():
  53. jc = JitCounter(size=4) # 2 bits
  54. incr = jc.compute_threshold(4)
  55. for i in range(5):
  56. for sk in range(100, 105):
  57. r = jc.tick(index2hash(jc, 3, subhash=sk), incr)
  58. assert r is (i == 3)
  59. jc = JitCounter()
  60. incr = jc.compute_threshold(4)
  61. misses = 0
  62. for i in range(5):
  63. for sk in range(100, 106):
  64. r = jc.tick(index2hash(jc, 3, subhash=sk), incr)
  65. if r:
  66. assert i == 3
  67. elif i == 3:
  68. misses += 1
  69. assert misses < 5
  70. def test_install_new_chain():
  71. class Dead:
  72. next = None
  73. def should_remove_jitcell(self):
  74. return True
  75. class Alive:
  76. next = None
  77. def should_remove_jitcell(self):
  78. return False
  79. #
  80. jc = JitCounter()
  81. assert jc.lookup_chain(104) is None
  82. d1 = Dead()
  83. jc.install_new_cell(104, d1)
  84. assert jc.lookup_chain(104) is d1
  85. d2 = Dead()
  86. jc.install_new_cell(104, d2)
  87. assert jc.lookup_chain(104) is d2
  88. assert d2.next is None
  89. #
  90. d3 = Alive()
  91. jc.install_new_cell(104, d3)
  92. assert jc.lookup_chain(104) is d3
  93. assert d3.next is None
  94. d4 = Alive()
  95. jc.install_new_cell(104, d4)
  96. assert jc.lookup_chain(104) is d3
  97. assert d3.next is d4
  98. assert d4.next is None
  99. def test_change_current_fraction():
  100. jc = JitCounter()
  101. incr = jc.compute_threshold(8)
  102. # change_current_fraction() with a fresh new hash
  103. jc.change_current_fraction(index2hash(jc, 104), 0.95)
  104. r = jc.tick(index2hash(jc, 104), incr)
  105. assert r is True
  106. # change_current_fraction() with an already-existing hash
  107. r = jc.tick(index2hash(jc, 104), incr)
  108. assert r is False
  109. jc.change_current_fraction(index2hash(jc, 104), 0.95)
  110. r = jc.tick(index2hash(jc, 104), incr)
  111. assert r is True
  112. # change_current_fraction() with a smaller incr
  113. incr = jc.compute_threshold(32)
  114. jc.change_current_fraction(index2hash(jc, 104), 0.95)
  115. r = jc.tick(index2hash(jc, 104), incr)
  116. assert r is False
  117. r = jc.tick(index2hash(jc, 104), incr)
  118. assert r is True