PageRenderTime 39ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/rpython/jit/backend/x86/runner.py

https://bitbucket.org/pypy/pypy/
Python | 157 lines | 137 code | 15 blank | 5 comment | 6 complexity | 3ce38ae260f3f7eee1b1ad405f16b9cb MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. import py
  2. from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
  3. from rpython.rlib.jit_hooks import LOOP_RUN_CONTAINER
  4. from rpython.rlib import rgc
  5. from rpython.jit.backend.x86.assembler import Assembler386
  6. from rpython.jit.backend.x86.regalloc import gpr_reg_mgr_cls, xmm_reg_mgr_cls
  7. from rpython.jit.backend.x86.profagent import ProfileAgent
  8. from rpython.jit.backend.llsupport.llmodel import AbstractLLCPU
  9. from rpython.jit.backend.x86 import regloc
  10. import sys
  11. class AbstractX86CPU(AbstractLLCPU):
  12. debug = True
  13. supports_floats = True
  14. supports_singlefloats = True
  15. dont_keepalive_stuff = False # for tests
  16. with_threads = False
  17. frame_reg = regloc.ebp
  18. # can an ISA instruction handle a factor to the offset?
  19. load_supported_factors = (1,2,4,8)
  20. from rpython.jit.backend.x86.arch import JITFRAME_FIXED_SIZE
  21. all_reg_indexes = gpr_reg_mgr_cls.all_reg_indexes
  22. gen_regs = gpr_reg_mgr_cls.all_regs
  23. float_regs = xmm_reg_mgr_cls.all_regs
  24. def __init__(self, rtyper, stats, opts=None, translate_support_code=False,
  25. gcdescr=None):
  26. AbstractLLCPU.__init__(self, rtyper, stats, opts,
  27. translate_support_code, gcdescr)
  28. profile_agent = ProfileAgent()
  29. if rtyper is not None:
  30. config = rtyper.annotator.translator.config
  31. if config.translation.jit_profiler == "oprofile":
  32. from rpython.jit.backend.x86 import oprofile
  33. if not oprofile.OPROFILE_AVAILABLE:
  34. log.WARNING('oprofile support was explicitly enabled, but oprofile headers seem not to be available')
  35. profile_agent = oprofile.OProfileAgent()
  36. self.with_threads = config.translation.thread
  37. self.profile_agent = profile_agent
  38. def set_debug(self, flag):
  39. return self.assembler.set_debug(flag)
  40. def setup(self):
  41. self.assembler = Assembler386(self, self.translate_support_code)
  42. def build_regalloc(self):
  43. ''' for tests'''
  44. from rpython.jit.backend.x86.regalloc import RegAlloc
  45. assert self.assembler is not None
  46. return RegAlloc(self.assembler, False)
  47. @rgc.no_release_gil
  48. def setup_once(self):
  49. self.profile_agent.startup()
  50. if self.HAS_CODEMAP:
  51. self.codemap.setup()
  52. self.assembler.setup_once()
  53. @rgc.no_release_gil
  54. def finish_once(self):
  55. self.assembler.finish_once()
  56. self.profile_agent.shutdown()
  57. def dump_loop_token(self, looptoken):
  58. """
  59. NOT_RPYTHON
  60. """
  61. from rpython.jit.backend.x86.tool.viewcode import machine_code_dump
  62. data = []
  63. label_list = [(offset, name) for name, offset in
  64. looptoken._x86_ops_offset.iteritems()]
  65. label_list.sort()
  66. addr = looptoken._x86_rawstart
  67. src = rffi.cast(rffi.CCHARP, addr)
  68. for p in range(looptoken._x86_fullsize):
  69. data.append(src[p])
  70. data = ''.join(data)
  71. lines = machine_code_dump(data, addr, self.backend_name, label_list)
  72. print ''.join(lines)
  73. def compile_bridge(self, faildescr, inputargs, operations,
  74. original_loop_token, log=True, logger=None):
  75. clt = original_loop_token.compiled_loop_token
  76. clt.compiling_a_bridge()
  77. return self.assembler.assemble_bridge(faildescr, inputargs, operations,
  78. original_loop_token, log, logger)
  79. def cast_ptr_to_int(x):
  80. adr = llmemory.cast_ptr_to_adr(x)
  81. return CPU386.cast_adr_to_int(adr)
  82. cast_ptr_to_int._annspecialcase_ = 'specialize:arglltype(0)'
  83. cast_ptr_to_int = staticmethod(cast_ptr_to_int)
  84. def redirect_call_assembler(self, oldlooptoken, newlooptoken):
  85. self.assembler.redirect_call_assembler(oldlooptoken, newlooptoken)
  86. def invalidate_loop(self, looptoken):
  87. from rpython.jit.backend.x86 import codebuf
  88. for addr, tgt in looptoken.compiled_loop_token.invalidate_positions:
  89. mc = codebuf.MachineCodeBlockWrapper()
  90. mc.JMP_l(tgt)
  91. assert mc.get_relative_pos() == 5 # [JMP] [tgt 4 bytes]
  92. mc.copy_to_raw_memory(addr - 1)
  93. # positions invalidated
  94. looptoken.compiled_loop_token.invalidate_positions = []
  95. def get_all_loop_runs(self):
  96. asm = self.assembler
  97. l = lltype.malloc(LOOP_RUN_CONTAINER,
  98. len(asm.loop_run_counters))
  99. for i, ll_s in enumerate(asm.loop_run_counters):
  100. l[i].type = ll_s.type
  101. l[i].number = ll_s.number
  102. l[i].counter = ll_s.i
  103. return l
  104. class CPU386(AbstractX86CPU):
  105. backend_name = 'x86'
  106. NUM_REGS = 8
  107. CALLEE_SAVE_REGISTERS = [regloc.ebx, regloc.esi, regloc.edi]
  108. supports_longlong = True
  109. IS_64_BIT = False
  110. def __init__(self, *args, **kwargs):
  111. assert sys.maxint == (2**31 - 1)
  112. super(CPU386, self).__init__(*args, **kwargs)
  113. class CPU386_NO_SSE2(CPU386):
  114. supports_floats = False
  115. supports_longlong = False
  116. class CPU_X86_64(AbstractX86CPU):
  117. backend_name = 'x86_64'
  118. NUM_REGS = 16
  119. CALLEE_SAVE_REGISTERS = [regloc.ebx, regloc.r12, regloc.r13, regloc.r14, regloc.r15]
  120. IS_64_BIT = True
  121. HAS_CODEMAP = True
  122. class CPU_X86_64_SSE4(CPU_X86_64):
  123. vector_extension = True
  124. vector_register_size = 16
  125. vector_horizontal_operations = True
  126. CPU = CPU386