PageRenderTime 24ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/rpython/jit/backend/llsupport/callbuilder.py

https://bitbucket.org/pypy/pypy/
Python | 104 lines | 95 code | 5 blank | 4 comment | 0 complexity | 46b95a241f1b4ca6f1f1692cc878ff84 MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. from rpython.rlib.clibffi import FFI_DEFAULT_ABI
  2. from rpython.rlib import rgil
  3. from rpython.rtyper.lltypesystem import lltype, rffi
  4. class AbstractCallBuilder(object):
  5. # this is the calling convention (can be FFI_STDCALL on Windows)
  6. callconv = FFI_DEFAULT_ABI
  7. # is it for the main CALL of a call_release_gil?
  8. is_call_release_gil = False
  9. # this can be set to guide more complex calls: gives the detailed
  10. # type of the arguments
  11. argtypes = ""
  12. ressign = False
  13. def __init__(self, assembler, fnloc, arglocs, resloc, restype, ressize):
  14. self.fnloc = fnloc
  15. self.arglocs = arglocs
  16. self.asm = assembler
  17. self.mc = assembler.mc
  18. self.resloc = resloc
  19. self.restype = restype
  20. self.ressize = ressize
  21. def emit_no_collect(self):
  22. """Emit a call that cannot collect."""
  23. self.prepare_arguments()
  24. self.emit_raw_call()
  25. self.restore_stack_pointer()
  26. self.load_result()
  27. def emit(self):
  28. """Emit a regular call; not for CALL_RELEASE_GIL."""
  29. self.prepare_arguments()
  30. self.push_gcmap()
  31. self.emit_raw_call()
  32. self.restore_stack_pointer()
  33. self.pop_gcmap()
  34. self.load_result()
  35. def emit_call_release_gil(self, save_err):
  36. """Emit a CALL_RELEASE_GIL, including calls to releasegil_addr
  37. and reacqgil_addr. 'save_err' is a combination of rffi.RFFI_*ERR*."""
  38. fastgil = rffi.cast(lltype.Signed, rgil.gil_fetch_fastgil())
  39. self.select_call_release_gil_mode()
  40. self.prepare_arguments()
  41. self.push_gcmap_for_call_release_gil()
  42. self.call_releasegil_addr_and_move_real_arguments(fastgil)
  43. self.write_real_errno(save_err)
  44. self.emit_raw_call()
  45. self.restore_stack_pointer()
  46. self.read_real_errno(save_err)
  47. self.move_real_result_and_call_reacqgil_addr(fastgil)
  48. self.pop_gcmap()
  49. self.load_result()
  50. def call_releasegil_addr_and_move_real_arguments(self, fastgil):
  51. raise NotImplementedError
  52. def move_real_result_and_call_reacqgil_addr(self, fastgil):
  53. raise NotImplementedError
  54. def write_real_errno(self, save_err):
  55. raise NotImplementedError
  56. def read_real_errno(self, save_err):
  57. raise NotImplementedError
  58. def select_call_release_gil_mode(self):
  59. """Overridden in CallBuilder64"""
  60. self.is_call_release_gil = True
  61. def prepare_arguments(self):
  62. raise NotImplementedError
  63. def push_gcmap(self):
  64. raise NotImplementedError
  65. def push_gcmap_for_call_release_gil(self):
  66. assert self.is_call_release_gil
  67. # we put the gcmap now into the frame before releasing the GIL,
  68. # and pop it after reacquiring the GIL. The assumption
  69. # is that this gcmap describes correctly the situation at any
  70. # point in-between: all values containing GC pointers should
  71. # be safely saved out of registers by now, and will not be
  72. # manipulated by any of the following CALLs.
  73. gcmap = self.asm._regalloc.get_gcmap(noregs=True)
  74. self.asm.push_gcmap(self.mc, gcmap, store=True)
  75. def pop_gcmap(self):
  76. raise NotImplementedError
  77. def emit_raw_call(self):
  78. raise NotImplementedError
  79. def restore_stack_pointer(self):
  80. raise NotImplementedError
  81. def load_result(self):
  82. raise NotImplementedError