[pypy-commit] pypy jitframe-on-heap: partial support for malloc slow- and fast-path for ARM
bivab
noreply at buildbot.pypy.org
Tue Mar 12 10:22:25 CET 2013
Author: David Schneider <david.schneider at picle.org>
Branch: jitframe-on-heap
Changeset: r62310:26cb6699b110
Date: 2013-03-12 10:18 +0100
http://bitbucket.org/pypy/pypy/changeset/26cb6699b110/
Log: partial support for malloc slow- and fast-path for ARM
diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py
--- a/rpython/jit/backend/arm/assembler.py
+++ b/rpython/jit/backend/arm/assembler.py
@@ -180,7 +180,6 @@
if not self.cpu.propagate_exception_descr:
return # not supported (for tests, or non-translated)
#
- #
mc = ARMv7Builder()
self._store_and_reset_exception(mc, r.r0)
ofs = self.cpu.get_ofs_of_frame_field('jf_guard_exc')
@@ -358,35 +357,60 @@
def _build_malloc_slowpath(self):
mc = ARMv7Builder()
- if self.cpu.supports_floats:
- vfp_regs = r.all_vfp_regs
- else:
- vfp_regs = []
+ self._push_all_regs_to_jitframe(mc, [r.r0, r.r1], self.cpu.supports_floats)
+ ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap')
+ # store the gc pattern
+ mc.POP([r.r2.value])
+ self.store_reg(mc, r.r2, r.fp, ofs)
# We need to push two registers here because we are going to make a
# call an therefore the stack needs to be 8-byte aligned
mc.PUSH([r.ip.value, r.lr.value])
- with saved_registers(mc, [], vfp_regs):
- # At this point we know that the values we need to compute the size
- # are stored in r0 and r1.
- mc.SUB_rr(r.r0.value, r.r1.value, r.r0.value)
- addr = self.cpu.gc_ll_descr.get_malloc_slowpath_addr()
- for reg, ofs in CoreRegisterManager.REGLOC_TO_COPY_AREA_OFS.items():
- mc.STR_ri(reg.value, r.fp.value, imm=ofs)
- mc.BL(addr)
- for reg, ofs in CoreRegisterManager.REGLOC_TO_COPY_AREA_OFS.items():
- mc.LDR_ri(reg.value, r.fp.value, imm=ofs)
+ # At this point we know that the values we need to compute the size
+ # are stored in r0 and r1.
+ mc.SUB_rr(r.r0.value, r.r1.value, r.r0.value) # compute the size we want
+ if hasattr(self.cpu.gc_ll_descr, 'passes_frame'):
+ mc.MOV_rr(r.r1.value, r.fp.value)
+
+ addr = self.cpu.gc_ll_descr.get_malloc_slowpath_addr()
+ mc.BL(addr)
+
+ #
+ # If the slowpath malloc failed, we raise a MemoryError that
+ # always interrupts the current loop, as a "good enough"
+ # approximation.
mc.CMP_ri(r.r0.value, 0)
mc.B(self.propagate_exception_path, c=c.EQ)
+ #
+ self._reload_frame_if_necessary(mc, align_stack=True)
+ self._pop_all_regs_from_jitframe(mc, [r.r0, r.r1], self.cpu.supports_floats)
+ #
nursery_free_adr = self.cpu.gc_ll_descr.get_nursery_free_addr()
mc.gen_load_int(r.r1.value, nursery_free_adr)
mc.LDR_ri(r.r1.value, r.r1.value)
- # see above
+ # clear the gc pattern
+ mc.gen_load_int(r.ip.value, 0)
+ self.store_reg(mc, r.ip, r.fp, ofs)
+ # return
mc.POP([r.ip.value, r.pc.value])
rawstart = mc.materialize(self.cpu.asmmemmgr, [])
self.malloc_slowpath = rawstart
+ def _reload_frame_if_necessary(self, mc, align_stack=False, can_collect=0):
+ gcrootmap = self.cpu.gc_ll_descr.gcrootmap
+ if gcrootmap and gcrootmap.is_shadow_stack:
+ import pdb; pdb.set_trace()
+ rst = gcrootmap.get_root_stack_top_addr()
+ mc.MOV(ecx, heap(rst))
+ mc.MOV(ebp, mem(ecx, -WORD))
+ wbdescr = self.cpu.gc_ll_descr.write_barrier_descr
+ if gcrootmap and wbdescr:
+ # frame never uses card marking, so we enforce this is not
+ # an array
+ self._write_barrier_fastpath(mc, wbdescr, [r.fp], array=False,
+ is_frame=True)#, align_stack=align_stack)
+
def propagate_memoryerror_if_r0_is_null(self):
# see ../x86/assembler.py:propagate_memoryerror_if_eax_is_null
self.mc.CMP_ri(r.r0.value, 0)
@@ -1223,7 +1247,7 @@
else:
raise AssertionError('Trying to pop to an invalid location')
- def malloc_cond(self, gcmap, nursery_free_adr, nursery_top_adr, size):
+ def malloc_cond(self, nursery_free_adr, nursery_top_adr, size, gcmap):
assert size & (WORD-1) == 0 # must be correctly aligned
self.mc.gen_load_int(r.r0.value, nursery_free_adr)
@@ -1247,23 +1271,23 @@
# malloc_slowpath in case we called malloc_slowpath, which returns the
# new value of nursery_free_adr in r1 and the adr of the new object in
# r0.
- XXX # push gcmap
-
+ self.push_gcmap(self.mc, gcmap, push=True, cond=c.HI)
+
self.mc.BL(self.malloc_slowpath, c=c.HI)
self.mc.gen_load_int(r.ip.value, nursery_free_adr)
self.mc.STR_ri(r.r1.value, r.ip.value)
- def push_gcmap(self, mc, gcmap, push=False, store=False):
+ def push_gcmap(self, mc, gcmap, push=False, store=False, cond=c.AL):
ptr = rffi.cast(lltype.Signed, gcmap)
if push:
- mc.gen_load_int(r.ip.value, ptr)
- mc.PUSH([r.ip.value])
+ mc.gen_load_int(r.ip.value, ptr, cond=cond)
+ mc.PUSH([r.ip.value], cond=cond)
else:
assert store
ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap')
- mc.gen_load_int(r.ip.value, ptr)
- mc.STR_ri(r.ip.value, r.fp.value, imm=ofs)
+ mc.gen_load_int(r.ip.value, ptr, cond=cond)
+ mc.STR_ri(r.ip.value, r.fp.value, imm=ofs, cond=cond)
def pop_gcmap(self, mc):
ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap')
diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py
--- a/rpython/jit/backend/arm/opassembler.py
+++ b/rpython/jit/backend/arm/opassembler.py
@@ -1316,10 +1316,10 @@
gc_ll_descr = self.cpu.gc_ll_descr
gcmap = regalloc.get_gcmap([r.r0, r.r1])
self.malloc_cond(
- gcmap,
gc_ll_descr.get_nursery_free_addr(),
gc_ll_descr.get_nursery_top_addr(),
- size
+ size,
+ gcmap
)
self._alignment_check()
return fcond
More information about the pypy-commit
mailing list