PageRenderTime 55ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/pypy/jit/backend/llsupport/llmodel.py

http://github.com/pypy/pypy
Python | 657 lines | 508 code | 95 blank | 54 comment | 47 complexity | a5684e2b9b2dca040eb0b2bda2e04182 MD5 | raw file
  1. from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rclass, rstr
  2. from pypy.rpython.lltypesystem.lloperation import llop
  3. from pypy.rpython.llinterp import LLInterpreter
  4. from pypy.rpython.annlowlevel import llhelper
  5. from pypy.rlib.objectmodel import we_are_translated, specialize
  6. from pypy.jit.metainterp import history
  7. from pypy.jit.codewriter import heaptracker, longlong
  8. from pypy.jit.backend.model import AbstractCPU
  9. from pypy.jit.backend.llsupport import symbolic
  10. from pypy.jit.backend.llsupport.symbolic import WORD, unroll_basic_sizes
  11. from pypy.jit.backend.llsupport.descr import (
  12. get_size_descr, get_field_descr, get_array_descr,
  13. get_call_descr, get_interiorfield_descr, get_dynamic_interiorfield_descr,
  14. FieldDescr, ArrayDescr, CallDescr, InteriorFieldDescr, get_dynamic_field_descr)
  15. from pypy.jit.backend.llsupport.asmmemmgr import AsmMemoryManager
  16. class AbstractLLCPU(AbstractCPU):
  17. from pypy.jit.metainterp.typesystem import llhelper as ts
  18. def __init__(self, rtyper, stats, opts, translate_support_code=False,
  19. gcdescr=None):
  20. assert type(opts) is not bool
  21. self.opts = opts
  22. from pypy.jit.backend.llsupport.gc import get_ll_description
  23. AbstractCPU.__init__(self)
  24. self.rtyper = rtyper
  25. self.stats = stats
  26. self.translate_support_code = translate_support_code
  27. if translate_support_code:
  28. translator = rtyper.annotator.translator
  29. else:
  30. translator = None
  31. self.gc_ll_descr = get_ll_description(gcdescr, translator, rtyper)
  32. if translator and translator.config.translation.gcremovetypeptr:
  33. self.vtable_offset = None
  34. else:
  35. self.vtable_offset, _ = symbolic.get_field_token(rclass.OBJECT,
  36. 'typeptr',
  37. translate_support_code)
  38. self._setup_prebuilt_error('ovf', OverflowError)
  39. self._setup_prebuilt_error('zer', ZeroDivisionError)
  40. if translate_support_code:
  41. self._setup_exception_handling_translated()
  42. else:
  43. self._setup_exception_handling_untranslated()
  44. self.saved_exc_value = lltype.nullptr(llmemory.GCREF.TO)
  45. self.asmmemmgr = AsmMemoryManager()
  46. self.setup()
  47. if translate_support_code:
  48. self._setup_on_leave_jitted_translated()
  49. else:
  50. self._setup_on_leave_jitted_untranslated()
  51. def setup(self):
  52. pass
  53. def _setup_prebuilt_error(self, prefix, Class):
  54. if self.rtyper is not None: # normal case
  55. bk = self.rtyper.annotator.bookkeeper
  56. clsdef = bk.getuniqueclassdef(Class)
  57. ll_inst = self.rtyper.exceptiondata.get_standard_ll_exc_instance(
  58. self.rtyper, clsdef)
  59. else:
  60. # for tests, a random emulated ll_inst will do
  61. ll_inst = lltype.malloc(rclass.OBJECT)
  62. ll_inst.typeptr = lltype.malloc(rclass.OBJECT_VTABLE,
  63. immortal=True)
  64. setattr(self, '_%s_error_vtable' % prefix,
  65. llmemory.cast_ptr_to_adr(ll_inst.typeptr))
  66. setattr(self, '_%s_error_inst' % prefix, ll_inst)
  67. def _setup_exception_handling_untranslated(self):
  68. # for running un-translated only, all exceptions occurring in the
  69. # llinterpreter are stored in '_exception_emulator', which is then
  70. # read back by the machine code reading at the address given by
  71. # pos_exception() and pos_exc_value().
  72. _exception_emulator = lltype.malloc(rffi.CArray(lltype.Signed), 2,
  73. zero=True, flavor='raw',
  74. immortal=True)
  75. self._exception_emulator = _exception_emulator
  76. def _store_exception(lle):
  77. self._last_exception = lle # keepalive
  78. tp_i = rffi.cast(lltype.Signed, lle.args[0])
  79. v_i = rffi.cast(lltype.Signed, lle.args[1])
  80. _exception_emulator[0] = tp_i
  81. _exception_emulator[1] = v_i
  82. self.debug_ll_interpreter = LLInterpreter(self.rtyper)
  83. self.debug_ll_interpreter._store_exception = _store_exception
  84. def pos_exception():
  85. return rffi.cast(lltype.Signed, _exception_emulator)
  86. def pos_exc_value():
  87. return (rffi.cast(lltype.Signed, _exception_emulator) +
  88. rffi.sizeof(lltype.Signed))
  89. def save_exception():
  90. # copy from _exception_emulator to the real attributes on self
  91. v_i = _exception_emulator[1]
  92. _exception_emulator[0] = 0
  93. _exception_emulator[1] = 0
  94. self.saved_exc_value = rffi.cast(llmemory.GCREF, v_i)
  95. def save_exception_memoryerr():
  96. save_exception()
  97. if not self.saved_exc_value:
  98. self.saved_exc_value = "memoryerror!" # for tests
  99. self.pos_exception = pos_exception
  100. self.pos_exc_value = pos_exc_value
  101. self.save_exception = save_exception
  102. self.save_exception_memoryerr = save_exception_memoryerr
  103. self.insert_stack_check = lambda: (0, 0, 0)
  104. def _setup_exception_handling_translated(self):
  105. def pos_exception():
  106. addr = llop.get_exception_addr(llmemory.Address)
  107. return heaptracker.adr2int(addr)
  108. def pos_exc_value():
  109. addr = llop.get_exc_value_addr(llmemory.Address)
  110. return heaptracker.adr2int(addr)
  111. def save_exception():
  112. addr = llop.get_exception_addr(llmemory.Address)
  113. addr.address[0] = llmemory.NULL
  114. addr = llop.get_exc_value_addr(llmemory.Address)
  115. exc_value = rffi.cast(llmemory.GCREF, addr.address[0])
  116. addr.address[0] = llmemory.NULL
  117. # from now on, the state is again consistent -- no more RPython
  118. # exception is set. The following code produces a write barrier
  119. # in the assignment to self.saved_exc_value, as needed.
  120. self.saved_exc_value = exc_value
  121. def save_exception_memoryerr():
  122. from pypy.rpython.annlowlevel import cast_instance_to_base_ptr
  123. save_exception()
  124. if not self.saved_exc_value:
  125. exc = MemoryError()
  126. exc = cast_instance_to_base_ptr(exc)
  127. exc = lltype.cast_opaque_ptr(llmemory.GCREF, exc)
  128. self.saved_exc_value = exc
  129. from pypy.rlib import rstack
  130. STACK_CHECK_SLOWPATH = lltype.Ptr(lltype.FuncType([lltype.Signed],
  131. lltype.Void))
  132. def insert_stack_check():
  133. endaddr = rstack._stack_get_end_adr()
  134. lengthaddr = rstack._stack_get_length_adr()
  135. f = llhelper(STACK_CHECK_SLOWPATH, rstack.stack_check_slowpath)
  136. slowpathaddr = rffi.cast(lltype.Signed, f)
  137. return endaddr, lengthaddr, slowpathaddr
  138. self.pos_exception = pos_exception
  139. self.pos_exc_value = pos_exc_value
  140. self.save_exception = save_exception
  141. self.save_exception_memoryerr = save_exception_memoryerr
  142. self.insert_stack_check = insert_stack_check
  143. def _setup_on_leave_jitted_untranslated(self):
  144. # assume we don't need a backend leave in this case
  145. self.on_leave_jitted_save_exc = self.save_exception
  146. self.on_leave_jitted_memoryerr = self.save_exception_memoryerr
  147. self.on_leave_jitted_noexc = lambda : None
  148. def _setup_on_leave_jitted_translated(self):
  149. on_leave_jitted_hook = self.get_on_leave_jitted_hook()
  150. save_exception = self.save_exception
  151. save_exception_memoryerr = self.save_exception_memoryerr
  152. def on_leave_jitted_noexc():
  153. on_leave_jitted_hook()
  154. def on_leave_jitted_save_exc():
  155. save_exception()
  156. on_leave_jitted_hook()
  157. def on_leave_jitted_memoryerr():
  158. save_exception_memoryerr()
  159. on_leave_jitted_hook()
  160. self.on_leave_jitted_noexc = on_leave_jitted_noexc
  161. self.on_leave_jitted_save_exc = on_leave_jitted_save_exc
  162. self.on_leave_jitted_memoryerr = on_leave_jitted_memoryerr
  163. def get_on_leave_jitted_hook(self):
  164. return lambda : None
  165. _ON_JIT_LEAVE_FUNC = lltype.Ptr(lltype.FuncType([], lltype.Void))
  166. def get_on_leave_jitted_int(self, save_exception,
  167. default_to_memoryerror=False):
  168. if default_to_memoryerror:
  169. f = llhelper(self._ON_JIT_LEAVE_FUNC, self.on_leave_jitted_memoryerr)
  170. elif save_exception:
  171. f = llhelper(self._ON_JIT_LEAVE_FUNC, self.on_leave_jitted_save_exc)
  172. else:
  173. f = llhelper(self._ON_JIT_LEAVE_FUNC, self.on_leave_jitted_noexc)
  174. return rffi.cast(lltype.Signed, f)
  175. def grab_exc_value(self):
  176. exc = self.saved_exc_value
  177. self.saved_exc_value = lltype.nullptr(llmemory.GCREF.TO)
  178. return exc
  179. def free_loop_and_bridges(self, compiled_loop_token):
  180. AbstractCPU.free_loop_and_bridges(self, compiled_loop_token)
  181. blocks = compiled_loop_token.asmmemmgr_blocks
  182. if blocks is not None:
  183. compiled_loop_token.asmmemmgr_blocks = None
  184. for rawstart, rawstop in blocks:
  185. self.gc_ll_descr.freeing_block(rawstart, rawstop)
  186. self.asmmemmgr.free(rawstart, rawstop)
  187. # ------------------- helpers and descriptions --------------------
  188. @staticmethod
  189. def _cast_int_to_gcref(x):
  190. # dangerous! only use if you are sure no collection could occur
  191. # between reading the integer and casting it to a pointer
  192. return rffi.cast(llmemory.GCREF, x)
  193. @staticmethod
  194. def cast_gcref_to_int(x):
  195. return rffi.cast(lltype.Signed, x)
  196. @staticmethod
  197. def cast_int_to_adr(x):
  198. return rffi.cast(llmemory.Address, x)
  199. @staticmethod
  200. def cast_adr_to_int(x):
  201. return rffi.cast(lltype.Signed, x)
  202. def sizeof(self, S):
  203. return get_size_descr(self.gc_ll_descr, S)
  204. def fielddescrof(self, STRUCT, fieldname):
  205. return get_field_descr(self.gc_ll_descr, STRUCT, fieldname)
  206. def fielddescrof_dynamic(self, offset, fieldsize, is_pointer, is_float, is_signed):
  207. return get_dynamic_field_descr(offset, fieldsize, is_pointer, is_float, is_signed)
  208. def unpack_fielddescr(self, fielddescr):
  209. assert isinstance(fielddescr, FieldDescr)
  210. return fielddescr.offset
  211. unpack_fielddescr._always_inline_ = True
  212. def unpack_fielddescr_size(self, fielddescr):
  213. assert isinstance(fielddescr, FieldDescr)
  214. ofs = fielddescr.offset
  215. size = fielddescr.field_size
  216. sign = fielddescr.is_field_signed()
  217. return ofs, size, sign
  218. unpack_fielddescr_size._always_inline_ = True
  219. def arraydescrof(self, A):
  220. return get_array_descr(self.gc_ll_descr, A)
  221. def interiorfielddescrof(self, A, fieldname):
  222. return get_interiorfield_descr(self.gc_ll_descr, A, fieldname)
  223. def interiorfielddescrof_dynamic(self, offset, width, fieldsize,
  224. is_pointer, is_float, is_signed):
  225. return get_dynamic_interiorfield_descr(self.gc_ll_descr,
  226. offset, width, fieldsize,
  227. is_pointer, is_float, is_signed)
  228. def unpack_arraydescr(self, arraydescr):
  229. assert isinstance(arraydescr, ArrayDescr)
  230. return arraydescr.basesize
  231. unpack_arraydescr._always_inline_ = True
  232. def unpack_arraydescr_size(self, arraydescr):
  233. assert isinstance(arraydescr, ArrayDescr)
  234. ofs = arraydescr.basesize
  235. size = arraydescr.itemsize
  236. sign = arraydescr.is_item_signed()
  237. return ofs, size, sign
  238. unpack_arraydescr_size._always_inline_ = True
  239. def calldescrof(self, FUNC, ARGS, RESULT, extrainfo):
  240. return get_call_descr(self.gc_ll_descr, ARGS, RESULT, extrainfo)
  241. def calldescrof_dynamic(self, ffi_args, ffi_result, extrainfo, ffi_flags):
  242. from pypy.jit.backend.llsupport import ffisupport
  243. return ffisupport.get_call_descr_dynamic(self, ffi_args, ffi_result,
  244. extrainfo, ffi_flags)
  245. def get_overflow_error(self):
  246. ovf_vtable = self.cast_adr_to_int(self._ovf_error_vtable)
  247. ovf_inst = lltype.cast_opaque_ptr(llmemory.GCREF,
  248. self._ovf_error_inst)
  249. return ovf_vtable, ovf_inst
  250. def get_zero_division_error(self):
  251. zer_vtable = self.cast_adr_to_int(self._zer_error_vtable)
  252. zer_inst = lltype.cast_opaque_ptr(llmemory.GCREF,
  253. self._zer_error_inst)
  254. return zer_vtable, zer_inst
  255. # ____________________________________________________________
  256. def bh_arraylen_gc(self, arraydescr, array):
  257. assert isinstance(arraydescr, ArrayDescr)
  258. ofs = arraydescr.lendescr.offset
  259. return rffi.cast(rffi.CArrayPtr(lltype.Signed), array)[ofs/WORD]
  260. @specialize.argtype(2)
  261. def bh_getarrayitem_gc_i(self, arraydescr, gcref, itemindex):
  262. ofs, size, sign = self.unpack_arraydescr_size(arraydescr)
  263. # --- start of GC unsafe code (no GC operation!) ---
  264. items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs)
  265. for STYPE, UTYPE, itemsize in unroll_basic_sizes:
  266. if size == itemsize:
  267. if sign:
  268. items = rffi.cast(rffi.CArrayPtr(STYPE), items)
  269. val = items[itemindex]
  270. val = rffi.cast(lltype.Signed, val)
  271. else:
  272. items = rffi.cast(rffi.CArrayPtr(UTYPE), items)
  273. val = items[itemindex]
  274. val = rffi.cast(lltype.Signed, val)
  275. # --- end of GC unsafe code ---
  276. return val
  277. else:
  278. raise NotImplementedError("size = %d" % size)
  279. def bh_getarrayitem_gc_r(self, arraydescr, gcref, itemindex):
  280. ofs = self.unpack_arraydescr(arraydescr)
  281. # --- start of GC unsafe code (no GC operation!) ---
  282. items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs)
  283. items = rffi.cast(rffi.CArrayPtr(lltype.Signed), items)
  284. pval = self._cast_int_to_gcref(items[itemindex])
  285. # --- end of GC unsafe code ---
  286. return pval
  287. @specialize.argtype(2)
  288. def bh_getarrayitem_gc_f(self, arraydescr, gcref, itemindex):
  289. ofs = self.unpack_arraydescr(arraydescr)
  290. # --- start of GC unsafe code (no GC operation!) ---
  291. items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs)
  292. items = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), items)
  293. fval = items[itemindex]
  294. # --- end of GC unsafe code ---
  295. return fval
  296. @specialize.argtype(2)
  297. def bh_setarrayitem_gc_i(self, arraydescr, gcref, itemindex, newvalue):
  298. ofs, size, sign = self.unpack_arraydescr_size(arraydescr)
  299. # --- start of GC unsafe code (no GC operation!) ---
  300. items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs)
  301. for TYPE, _, itemsize in unroll_basic_sizes:
  302. if size == itemsize:
  303. items = rffi.cast(rffi.CArrayPtr(TYPE), items)
  304. items[itemindex] = rffi.cast(TYPE, newvalue)
  305. # --- end of GC unsafe code ---
  306. return
  307. else:
  308. raise NotImplementedError("size = %d" % size)
  309. def bh_setarrayitem_gc_r(self, arraydescr, gcref, itemindex, newvalue):
  310. ofs = self.unpack_arraydescr(arraydescr)
  311. self.gc_ll_descr.do_write_barrier(gcref, newvalue)
  312. # --- start of GC unsafe code (no GC operation!) ---
  313. items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs)
  314. items = rffi.cast(rffi.CArrayPtr(lltype.Signed), items)
  315. items[itemindex] = self.cast_gcref_to_int(newvalue)
  316. # --- end of GC unsafe code ---
  317. @specialize.argtype(2)
  318. def bh_setarrayitem_gc_f(self, arraydescr, gcref, itemindex, newvalue):
  319. ofs = self.unpack_arraydescr(arraydescr)
  320. # --- start of GC unsafe code (no GC operation!) ---
  321. items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs)
  322. items = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), items)
  323. items[itemindex] = newvalue
  324. # --- end of GC unsafe code ---
  325. bh_setarrayitem_raw_i = bh_setarrayitem_gc_i
  326. bh_setarrayitem_raw_f = bh_setarrayitem_gc_f
  327. bh_getarrayitem_raw_i = bh_getarrayitem_gc_i
  328. bh_getarrayitem_raw_f = bh_getarrayitem_gc_f
  329. def bh_getinteriorfield_gc_i(self, gcref, itemindex, descr):
  330. assert isinstance(descr, InteriorFieldDescr)
  331. arraydescr = descr.arraydescr
  332. ofs, size, _ = self.unpack_arraydescr_size(arraydescr)
  333. ofs += descr.fielddescr.offset
  334. fieldsize = descr.fielddescr.field_size
  335. sign = descr.fielddescr.is_field_signed()
  336. fullofs = itemindex * size + ofs
  337. # --- start of GC unsafe code (no GC operation!) ---
  338. items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), fullofs)
  339. for STYPE, UTYPE, itemsize in unroll_basic_sizes:
  340. if fieldsize == itemsize:
  341. if sign:
  342. item = rffi.cast(rffi.CArrayPtr(STYPE), items)
  343. val = item[0]
  344. val = rffi.cast(lltype.Signed, val)
  345. else:
  346. item = rffi.cast(rffi.CArrayPtr(UTYPE), items)
  347. val = item[0]
  348. val = rffi.cast(lltype.Signed, val)
  349. # --- end of GC unsafe code ---
  350. return val
  351. else:
  352. raise NotImplementedError("size = %d" % fieldsize)
  353. def bh_getinteriorfield_gc_r(self, gcref, itemindex, descr):
  354. assert isinstance(descr, InteriorFieldDescr)
  355. arraydescr = descr.arraydescr
  356. ofs, size, _ = self.unpack_arraydescr_size(arraydescr)
  357. ofs += descr.fielddescr.offset
  358. # --- start of GC unsafe code (no GC operation!) ---
  359. items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs +
  360. size * itemindex)
  361. items = rffi.cast(rffi.CArrayPtr(lltype.Signed), items)
  362. pval = self._cast_int_to_gcref(items[0])
  363. # --- end of GC unsafe code ---
  364. return pval
  365. def bh_getinteriorfield_gc_f(self, gcref, itemindex, descr):
  366. assert isinstance(descr, InteriorFieldDescr)
  367. arraydescr = descr.arraydescr
  368. ofs, size, _ = self.unpack_arraydescr_size(arraydescr)
  369. ofs += descr.fielddescr.offset
  370. # --- start of GC unsafe code (no GC operation!) ---
  371. items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs +
  372. size * itemindex)
  373. items = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), items)
  374. fval = items[0]
  375. # --- end of GC unsafe code ---
  376. return fval
  377. def bh_setinteriorfield_gc_i(self, gcref, itemindex, descr, value):
  378. assert isinstance(descr, InteriorFieldDescr)
  379. arraydescr = descr.arraydescr
  380. ofs, size, _ = self.unpack_arraydescr_size(arraydescr)
  381. ofs += descr.fielddescr.offset
  382. fieldsize = descr.fielddescr.field_size
  383. ofs = itemindex * size + ofs
  384. # --- start of GC unsafe code (no GC operation!) ---
  385. items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs)
  386. for TYPE, _, itemsize in unroll_basic_sizes:
  387. if fieldsize == itemsize:
  388. items = rffi.cast(rffi.CArrayPtr(TYPE), items)
  389. items[0] = rffi.cast(TYPE, value)
  390. # --- end of GC unsafe code ---
  391. return
  392. else:
  393. raise NotImplementedError("size = %d" % fieldsize)
  394. def bh_setinteriorfield_gc_r(self, gcref, itemindex, descr, newvalue):
  395. assert isinstance(descr, InteriorFieldDescr)
  396. arraydescr = descr.arraydescr
  397. ofs, size, _ = self.unpack_arraydescr_size(arraydescr)
  398. ofs += descr.fielddescr.offset
  399. self.gc_ll_descr.do_write_barrier(gcref, newvalue)
  400. # --- start of GC unsafe code (no GC operation!) ---
  401. items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref),
  402. ofs + size * itemindex)
  403. items = rffi.cast(rffi.CArrayPtr(lltype.Signed), items)
  404. items[0] = self.cast_gcref_to_int(newvalue)
  405. # --- end of GC unsafe code ---
  406. def bh_setinteriorfield_gc_f(self, gcref, itemindex, descr, newvalue):
  407. assert isinstance(descr, InteriorFieldDescr)
  408. arraydescr = descr.arraydescr
  409. ofs, size, _ = self.unpack_arraydescr_size(arraydescr)
  410. ofs += descr.fielddescr.offset
  411. # --- start of GC unsafe code (no GC operation!) ---
  412. items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref),
  413. ofs + size * itemindex)
  414. items = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), items)
  415. items[0] = newvalue
  416. # --- end of GC unsafe code ---
  417. def bh_strlen(self, string):
  418. s = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), string)
  419. return len(s.chars)
  420. def bh_unicodelen(self, string):
  421. u = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), string)
  422. return len(u.chars)
  423. def bh_strgetitem(self, string, index):
  424. s = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), string)
  425. return ord(s.chars[index])
  426. def bh_unicodegetitem(self, string, index):
  427. u = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), string)
  428. return ord(u.chars[index])
  429. @specialize.argtype(1)
  430. def _base_do_getfield_i(self, struct, fielddescr):
  431. ofs, size, sign = self.unpack_fielddescr_size(fielddescr)
  432. # --- start of GC unsafe code (no GC operation!) ---
  433. fieldptr = rffi.ptradd(rffi.cast(rffi.CCHARP, struct), ofs)
  434. for STYPE, UTYPE, itemsize in unroll_basic_sizes:
  435. if size == itemsize:
  436. # Note that in the common case where size==sizeof(Signed),
  437. # both cases of what follows are doing the same thing.
  438. # But gcc is clever enough to figure this out :-)
  439. if sign:
  440. val = rffi.cast(rffi.CArrayPtr(STYPE), fieldptr)[0]
  441. val = rffi.cast(lltype.Signed, val)
  442. else:
  443. val = rffi.cast(rffi.CArrayPtr(UTYPE), fieldptr)[0]
  444. val = rffi.cast(lltype.Signed, val)
  445. # --- end of GC unsafe code ---
  446. return val
  447. else:
  448. raise NotImplementedError("size = %d" % size)
  449. @specialize.argtype(1)
  450. def _base_do_getfield_r(self, struct, fielddescr):
  451. ofs = self.unpack_fielddescr(fielddescr)
  452. # --- start of GC unsafe code (no GC operation!) ---
  453. fieldptr = rffi.ptradd(rffi.cast(rffi.CCHARP, struct), ofs)
  454. pval = rffi.cast(rffi.CArrayPtr(lltype.Signed), fieldptr)[0]
  455. pval = self._cast_int_to_gcref(pval)
  456. # --- end of GC unsafe code ---
  457. return pval
  458. @specialize.argtype(1)
  459. def _base_do_getfield_f(self, struct, fielddescr):
  460. ofs = self.unpack_fielddescr(fielddescr)
  461. # --- start of GC unsafe code (no GC operation!) ---
  462. fieldptr = rffi.ptradd(rffi.cast(rffi.CCHARP, struct), ofs)
  463. fval = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), fieldptr)[0]
  464. # --- end of GC unsafe code ---
  465. return fval
  466. bh_getfield_gc_i = _base_do_getfield_i
  467. bh_getfield_gc_r = _base_do_getfield_r
  468. bh_getfield_gc_f = _base_do_getfield_f
  469. bh_getfield_raw_i = _base_do_getfield_i
  470. bh_getfield_raw_r = _base_do_getfield_r
  471. bh_getfield_raw_f = _base_do_getfield_f
  472. @specialize.argtype(1)
  473. def _base_do_setfield_i(self, struct, fielddescr, newvalue):
  474. ofs, size, sign = self.unpack_fielddescr_size(fielddescr)
  475. # --- start of GC unsafe code (no GC operation!) ---
  476. fieldptr = rffi.ptradd(rffi.cast(rffi.CCHARP, struct), ofs)
  477. for TYPE, _, itemsize in unroll_basic_sizes:
  478. if size == itemsize:
  479. fieldptr = rffi.cast(rffi.CArrayPtr(TYPE), fieldptr)
  480. fieldptr[0] = rffi.cast(TYPE, newvalue)
  481. # --- end of GC unsafe code ---
  482. return
  483. else:
  484. raise NotImplementedError("size = %d" % size)
  485. @specialize.argtype(1)
  486. def _base_do_setfield_r(self, struct, fielddescr, newvalue):
  487. ofs = self.unpack_fielddescr(fielddescr)
  488. assert lltype.typeOf(struct) is not lltype.Signed, (
  489. "can't handle write barriers for setfield_raw")
  490. self.gc_ll_descr.do_write_barrier(struct, newvalue)
  491. # --- start of GC unsafe code (no GC operation!) ---
  492. fieldptr = rffi.ptradd(rffi.cast(rffi.CCHARP, struct), ofs)
  493. fieldptr = rffi.cast(rffi.CArrayPtr(lltype.Signed), fieldptr)
  494. fieldptr[0] = self.cast_gcref_to_int(newvalue)
  495. # --- end of GC unsafe code ---
  496. @specialize.argtype(1)
  497. def _base_do_setfield_f(self, struct, fielddescr, newvalue):
  498. ofs = self.unpack_fielddescr(fielddescr)
  499. # --- start of GC unsafe code (no GC operation!) ---
  500. fieldptr = rffi.ptradd(rffi.cast(rffi.CCHARP, struct), ofs)
  501. fieldptr = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), fieldptr)
  502. fieldptr[0] = newvalue
  503. # --- end of GC unsafe code ---
  504. bh_setfield_gc_i = _base_do_setfield_i
  505. bh_setfield_gc_r = _base_do_setfield_r
  506. bh_setfield_gc_f = _base_do_setfield_f
  507. bh_setfield_raw_i = _base_do_setfield_i
  508. bh_setfield_raw_r = _base_do_setfield_r
  509. bh_setfield_raw_f = _base_do_setfield_f
  510. def bh_new(self, sizedescr):
  511. return self.gc_ll_descr.gc_malloc(sizedescr)
  512. def bh_new_with_vtable(self, sizedescr, vtable):
  513. res = self.gc_ll_descr.gc_malloc(sizedescr)
  514. if self.vtable_offset is not None:
  515. as_array = rffi.cast(rffi.CArrayPtr(lltype.Signed), res)
  516. as_array[self.vtable_offset/WORD] = vtable
  517. return res
  518. def bh_classof(self, struct):
  519. struct = lltype.cast_opaque_ptr(rclass.OBJECTPTR, struct)
  520. result_adr = llmemory.cast_ptr_to_adr(struct.typeptr)
  521. return heaptracker.adr2int(result_adr)
  522. def bh_new_array(self, arraydescr, length):
  523. return self.gc_ll_descr.gc_malloc_array(arraydescr, length)
  524. def bh_newstr(self, length):
  525. return self.gc_ll_descr.gc_malloc_str(length)
  526. def bh_newunicode(self, length):
  527. return self.gc_ll_descr.gc_malloc_unicode(length)
  528. def bh_strsetitem(self, string, index, newvalue):
  529. s = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), string)
  530. s.chars[index] = chr(newvalue)
  531. def bh_unicodesetitem(self, string, index, newvalue):
  532. u = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), string)
  533. u.chars[index] = unichr(newvalue)
  534. def bh_copystrcontent(self, src, dst, srcstart, dststart, length):
  535. src = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), src)
  536. dst = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), dst)
  537. rstr.copy_string_contents(src, dst, srcstart, dststart, length)
  538. def bh_copyunicodecontent(self, src, dst, srcstart, dststart, length):
  539. src = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), src)
  540. dst = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), dst)
  541. rstr.copy_unicode_contents(src, dst, srcstart, dststart, length)
  542. def bh_call_i(self, func, calldescr, args_i, args_r, args_f):
  543. assert isinstance(calldescr, CallDescr)
  544. if not we_are_translated():
  545. calldescr.verify_types(args_i, args_r, args_f, history.INT + 'S')
  546. return calldescr.call_stub_i(func, args_i, args_r, args_f)
  547. def bh_call_r(self, func, calldescr, args_i, args_r, args_f):
  548. assert isinstance(calldescr, CallDescr)
  549. if not we_are_translated():
  550. calldescr.verify_types(args_i, args_r, args_f, history.REF)
  551. return calldescr.call_stub_r(func, args_i, args_r, args_f)
  552. def bh_call_f(self, func, calldescr, args_i, args_r, args_f):
  553. assert isinstance(calldescr, CallDescr)
  554. if not we_are_translated():
  555. calldescr.verify_types(args_i, args_r, args_f, history.FLOAT + 'L')
  556. return calldescr.call_stub_f(func, args_i, args_r, args_f)
  557. def bh_call_v(self, func, calldescr, args_i, args_r, args_f):
  558. assert isinstance(calldescr, CallDescr)
  559. if not we_are_translated():
  560. calldescr.verify_types(args_i, args_r, args_f, history.VOID)
  561. # the 'i' return value is ignored (and nonsense anyway)
  562. calldescr.call_stub_i(func, args_i, args_r, args_f)