[pypy-commit] pypy stmgc-c4: add weakref support and log rewritten jit trace
Raemi
noreply at buildbot.pypy.org
Mon Jul 22 17:56:41 CEST 2013
Author: Remi Meier <remi.meier at gmail.com>
Branch: stmgc-c4
Changeset: r65526:ac7d49c563e5
Date: 2013-07-22 17:55 +0200
http://bitbucket.org/pypy/pypy/changeset/ac7d49c563e5/
Log: add weakref support and log rewritten jit trace
diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py
--- a/rpython/jit/backend/x86/assembler.py
+++ b/rpython/jit/backend/x86/assembler.py
@@ -397,16 +397,24 @@
if IS_X86_32:
# we have 2 extra words on stack for retval and we pass 1 extra
# arg, so we need to substract 2 words
+ # ||val|retadr|
mc.SUB_ri(esp.value, 2 * WORD)
+ # ||val|retadr|x|x||
mc.MOV_rs(eax.value, 3 * WORD) # 2 + 1
mc.MOV_sr(0, eax.value)
+ # ||val|retadr|x|val||
else:
+ # ||val|retadr||
mc.MOV_rs(edi.value, WORD)
else:
+ # ||retadr|
# we have one word to align
mc.SUB_ri(esp.value, 7 * WORD) # align and reserve some space
+ # ||retadr|x||x|x||x|x||x|x||
mc.MOV_sr(WORD, eax.value) # save for later
+ # ||retadr|x||x|x||x|x||rax|x||
mc.MOVSD_sx(3 * WORD, xmm0.value)
+ # ||retadr|x||x|x||xmm0|x||rax|x||
if IS_X86_32:
mc.MOV_sr(4 * WORD, edx.value)
mc.MOV_sr(0, ebp.value)
@@ -427,19 +435,24 @@
if descr.returns_modified_object:
# new addr in eax, save to now unused arg
if for_frame:
+ # ||retadr|x||x|x||xmm0|x||rax|x||
mc.PUSH_r(eax.value)
+ # ||retadr|x||x|x||xmm0|x||rax|x||result|
elif IS_X86_32:
mc.MOV_sr(3 * WORD, eax.value)
+ # ||val|retadr|x|val||
+ # -> ||result|retaddr|x|val||
else:
mc.MOV_sr(WORD, eax.value)
+ # ||val|retadr|| -> ||result|retadr||
if withcards:
# A final TEST8 before the RET, for the caller. Careful to
# not follow this instruction with another one that changes
# the status of the CPU flags!
- assert not is_stm
+ assert not is_stm and not descr.returns_modified_object
if IS_X86_32:
- mc.MOV_rs(eax.value, 3*WORD)
+ mc.MOV_rs(eax.value, 3 * WORD)
else:
mc.MOV_rs(eax.value, WORD)
mc.TEST8(addr_add_const(eax, descr.jit_wb_if_flag_byteofs),
@@ -460,14 +473,18 @@
else:
if IS_X86_32:
mc.MOV_rs(edx.value, 5 * WORD)
+ # ||retadr|x||x|x||xmm0|x||rax|x||result|
mc.MOVSD_xs(xmm0.value, 4 * WORD)
mc.MOV_rs(eax.value, 2 * WORD) # restore
self._restore_exception(mc, exc0, exc1)
mc.MOV(exc0, RawEspLoc(WORD * 6, REF))
mc.MOV(exc1, RawEspLoc(WORD * 7, INT))
- mc.POP_r(eax.value) # return value
-
+ if IS_X86_32:
+ mc.POP_r(edx.value) # return value
+ else:
+ mc.POP_r(edi.value) # return value
+
mc.LEA_rs(esp.value, 7 * WORD)
mc.RET()
@@ -478,7 +495,8 @@
else:
descr.set_b_slowpath(withcards + 2 * withfloats, rawstart)
- def assemble_loop(self, loopname, inputargs, operations, looptoken, log):
+ def assemble_loop(self, loopname, inputargs, operations, looptoken, log,
+ logger=None):
'''adds the following attributes to looptoken:
_ll_function_addr (address of the generated func, as an int)
_ll_loop_code (debug: addr of the start of the ResOps)
@@ -513,6 +531,9 @@
self._check_frame_depth_debug(self.mc)
operations = regalloc.prepare_loop(inputargs, operations, looptoken,
clt.allgcrefs)
+ if logger:
+ logger.log_loop(inputargs, operations, -2, "rewritten",
+ name=loopname)
looppos = self.mc.get_relative_pos()
frame_depth_no_fixed_size = self._assemble(regalloc, inputargs,
operations)
@@ -554,7 +575,7 @@
size_excluding_failure_stuff - looppos)
def assemble_bridge(self, faildescr, inputargs, operations,
- original_loop_token, log):
+ original_loop_token, log, logger=None):
if not we_are_translated():
# Arguments should be unique
assert len(set(inputargs)) == len(inputargs)
@@ -572,6 +593,8 @@
operations,
self.current_clt.allgcrefs,
self.current_clt.frame_info)
+ if logger:
+ logger.log_bridge(inputargs, operations, "rewritten")
self._check_frame_depth(self.mc, regalloc.get_gcmap())
frame_depth_no_fixed_size = self._assemble(regalloc, inputargs, operations)
codeendpos = self.mc.get_relative_pos()
@@ -2138,10 +2161,21 @@
if not is_frame:
mc.PUSH(loc_base)
if is_frame and align_stack:
+ # ||retadr|
mc.SUB_ri(esp.value, 16 - WORD) # erase the return address
+ # ||retadr|...||
func = descr.get_b_slowpath(helper_num)
mc.CALL(imm(func))
- mc.MOV_rr(loc_base.value, eax.value)
+
+ # result in eax, except if is_frame
+ if is_frame:
+ if IS_X86_32:
+ mc.MOV_rr(loc_base.value, edx.value)
+ else:
+ mc.MOV_rr(loc_base.value, edi.value)
+ else:
+ mc.MOV_rr(loc_base.value, eax.value)
+
if is_frame and align_stack:
mc.ADD_ri(esp.value, 16 - WORD) # erase the return address
diff --git a/rpython/jit/backend/x86/runner.py b/rpython/jit/backend/x86/runner.py
--- a/rpython/jit/backend/x86/runner.py
+++ b/rpython/jit/backend/x86/runner.py
@@ -90,16 +90,18 @@
lines = machine_code_dump(data, addr, self.backend_name, label_list)
print ''.join(lines)
- def compile_loop(self, inputargs, operations, looptoken, log=True, name=''):
+ def compile_loop(self, inputargs, operations, looptoken, log=True, name='',
+ logger=None):
return self.assembler.assemble_loop(name, inputargs, operations,
- looptoken, log=log)
+ looptoken, log=log, logger=logger)
def compile_bridge(self, faildescr, inputargs, operations,
- original_loop_token, log=True):
+ original_loop_token, log=True, logger=None):
clt = original_loop_token.compiled_loop_token
clt.compiling_a_bridge()
return self.assembler.assemble_bridge(faildescr, inputargs, operations,
- original_loop_token, log=log)
+ original_loop_token, log=log,
+ logger=logger)
def clear_latest_values(self, count):
setitem = self.assembler.fail_boxes_ptr.setitem
diff --git a/rpython/jit/metainterp/compile.py b/rpython/jit/metainterp/compile.py
--- a/rpython/jit/metainterp/compile.py
+++ b/rpython/jit/metainterp/compile.py
@@ -303,14 +303,17 @@
metainterp_sd.logger_ops.log_loop(inputargs, operations, -2,
'compiling', name=name)
return metainterp_sd.cpu.compile_loop(inputargs, operations, looptoken,
- log=log, name=name)
+ log=log, name=name,
+ logger=metainterp_sd.logger_ops)
def do_compile_bridge(metainterp_sd, faildescr, inputargs, operations,
original_loop_token, log=True):
metainterp_sd.logger_ops.log_bridge(inputargs, operations, "compiling")
assert isinstance(faildescr, AbstractFailDescr)
return metainterp_sd.cpu.compile_bridge(faildescr, inputargs, operations,
- original_loop_token, log=log)
+ original_loop_token, log=log,
+ logger=metainterp_sd.logger_ops)
+
def send_loop_to_backend(greenkey, jitdriver_sd, metainterp_sd, loop, type):
vinfo = jitdriver_sd.virtualizable_info
diff --git a/rpython/jit/metainterp/logger.py b/rpython/jit/metainterp/logger.py
--- a/rpython/jit/metainterp/logger.py
+++ b/rpython/jit/metainterp/logger.py
@@ -39,6 +39,10 @@
debug_start("jit-log-compiling-bridge")
logops = self._log_operations(inputargs, operations, ops_offset)
debug_stop("jit-log-compiling-bridge")
+ elif extra == "rewritten":
+ debug_start("jit-log-rewritten-bridge")
+ logops = self._log_operations(inputargs, operations, ops_offset)
+ debug_stop("jit-log-rewritten-bridge")
else:
debug_start("jit-log-opt-bridge")
debug_print("# bridge out of Guard",
diff --git a/rpython/memory/gc/stmgc.py b/rpython/memory/gc/stmgc.py
--- a/rpython/memory/gc/stmgc.py
+++ b/rpython/memory/gc/stmgc.py
@@ -104,7 +104,7 @@
# XXX finalizers are ignored for now
#ll_assert(not needs_finalizer, 'XXX needs_finalizer')
#ll_assert(not is_finalizer_light, 'XXX is_finalizer_light')
- ll_assert(not contains_weakptr, 'XXX contains_weakptr')
+ #ll_assert(not contains_weakptr, 'XXX contains_weakptr')
# XXX call optimized versions, e.g. if size < GC_NURSERY_SECTION
return llop.stm_allocate(llmemory.GCREF, size, typeid16)
@@ -117,6 +117,9 @@
(obj + offset_to_length).signed[0] = length
return llmemory.cast_adr_to_ptr(obj, llmemory.GCREF)
+ def malloc_weakref(self, typeid16, size, obj):
+ return llop.stm_weakref_allocate(llmemory.GCREF, size,
+ typeid16, obj)
def can_move(self, obj):
"""Means the reference will stay valid, except if not
diff --git a/rpython/memory/gctransform/stmframework.py b/rpython/memory/gctransform/stmframework.py
--- a/rpython/memory/gctransform/stmframework.py
+++ b/rpython/memory/gctransform/stmframework.py
@@ -1,8 +1,10 @@
from rpython.annotator import model as annmodel
from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
from rpython.rtyper.lltypesystem.lloperation import llop
-from rpython.memory.gctransform.framework import (
+from rpython.memory.gctransform.framework import ( TYPE_ID,
BaseFrameworkGCTransformer, BaseRootWalker, sizeofaddr)
+from rpython.memory.gctypelayout import WEAKREF, WEAKREFPTR
+from rpython.rtyper import rmodel
class StmFrameworkGCTransformer(BaseFrameworkGCTransformer):
@@ -12,6 +14,13 @@
s_gc, s_typeid16)
gc = self.gcdata.gc
#
+ s_gcref = annmodel.SomePtr(llmemory.GCREF)
+
+ self.malloc_weakref_ptr = self._getfn(
+ GCClass.malloc_weakref.im_func,
+ [s_gc, s_typeid16, annmodel.SomeInteger(nonneg=True),
+ s_gcref], s_gcref)
+ #
def pypy_stmcb_size(obj):
return gc.get_size(obj)
pypy_stmcb_size.c_name = "pypy_stmcb_size"
@@ -49,6 +58,40 @@
def gct_gc_adr_of_root_stack_top(self, hop):
hop.genop("stm_get_root_stack_top", [], resultvar=hop.spaceop.result)
+ def gct_weakref_create(self, hop):
+ op = hop.spaceop
+
+ type_id = self.get_type_id(WEAKREF)
+
+ c_type_id = rmodel.inputconst(TYPE_ID, type_id)
+ info = self.layoutbuilder.get_info(type_id)
+ c_size = rmodel.inputconst(lltype.Signed, info.fixedsize)
+ malloc_ptr = self.malloc_weakref_ptr
+ c_null = rmodel.inputconst(llmemory.Address, llmemory.NULL)
+ args = [self.c_const_gc, c_type_id, c_size, c_null]
+ # XXX: for now, set weakptr ourselves and simply pass NULL
+
+ # push and pop the current live variables *including* the argument
+ # to the weakref_create operation, which must be kept alive and
+ # moved if the GC needs to collect
+ livevars = self.push_roots(hop, keep_current_args=True)
+ v_result = hop.genop("direct_call", [malloc_ptr] + args,
+ resulttype=llmemory.GCREF)
+ v_result = hop.genop("cast_opaque_ptr", [v_result],
+ resulttype=WEAKREFPTR)
+ self.pop_roots(hop, livevars)
+ # cast_ptr_to_adr must be done after malloc, as the GC pointer
+ # might have moved just now.
+ v_instance, = op.args
+ v_addr = hop.genop("cast_ptr_to_adr", [v_instance],
+ resulttype=llmemory.Address)
+ hop.genop("bare_setfield",
+ [v_result, rmodel.inputconst(lltype.Void, "weakptr"), v_addr])
+ v_weakref = hop.genop("cast_ptr_to_weakrefptr", [v_result],
+ resulttype=llmemory.WeakRefPtr)
+ hop.cast_result(v_weakref)
+
+
def _gct_with_roots_pushed(self, hop):
livevars = self.push_roots(hop)
self.default(hop)
diff --git a/rpython/rtyper/lltypesystem/lloperation.py b/rpython/rtyper/lltypesystem/lloperation.py
--- a/rpython/rtyper/lltypesystem/lloperation.py
+++ b/rpython/rtyper/lltypesystem/lloperation.py
@@ -445,6 +445,8 @@
'stm_leave_callback_call':LLOp(),
'stm_abort_and_retry': LLOp(),
+ 'stm_weakref_allocate': LLOp(sideeffects=False, canmallocgc=True),
+
'stm_threadlocalref_get': LLOp(sideeffects=False),
'stm_threadlocalref_set': LLOp(),
'stm_threadlocal_get': LLOp(sideeffects=False),
diff --git a/rpython/translator/c/funcgen.py b/rpython/translator/c/funcgen.py
--- a/rpython/translator/c/funcgen.py
+++ b/rpython/translator/c/funcgen.py
@@ -593,6 +593,7 @@
OP_STM_POP_ROOT_INTO = _OP_STM
OP_STM_GET_ROOT_STACK_TOP = _OP_STM
OP_STM_ALLOCATE = _OP_STM
+ OP_STM_WEAKREF_ALLOCATE = _OP_STM
OP_STM_GET_TID = _OP_STM
OP_STM_HASH = _OP_STM
OP_STM_ID = _OP_STM
diff --git a/rpython/translator/stm/funcgen.py b/rpython/translator/stm/funcgen.py
--- a/rpython/translator/stm/funcgen.py
+++ b/rpython/translator/stm/funcgen.py
@@ -99,6 +99,14 @@
return '%s = (%s)stm_shadowstack;' % (
result, cdecl(funcgen.lltypename(op.result), ''))
+def stm_weakref_allocate(funcgen, op):
+ arg0 = funcgen.expr(op.args[0])
+ arg1 = funcgen.expr(op.args[1])
+ arg2 = funcgen.expr(op.args[2])
+ result = funcgen.expr(op.result)
+ return '%s = stm_weakref_allocate(%s, %s, %s);' % (result, arg0,
+ arg1, arg2)
+
def stm_allocate(funcgen, op):
arg0 = funcgen.expr(op.args[0])
arg1 = funcgen.expr(op.args[1])
More information about the pypy-commit
mailing list