Author: Antonio Cuni <[email protected]>
Branch: refactor-call_release_gil
Changeset: r59871:90482eb028fe
Date: 2013-01-08 09:01 +0100
http://bitbucket.org/pypy/pypy/changeset/90482eb028fe/
Log: a branch where to fix this failing test about call_release_gil,
which is due to the fact that the op is generated inside pyjitpl and
thus its resultbox is not included in the guard_not_forced failargs
diff --git a/pypy/jit/backend/llgraph/runner.py
b/pypy/jit/backend/llgraph/runner.py
--- a/pypy/jit/backend/llgraph/runner.py
+++ b/pypy/jit/backend/llgraph/runner.py
@@ -820,10 +820,22 @@
# manipulation here (as a hack, instead of really doing
# the aroundstate manipulation ourselves)
return self.execute_call_may_force(descr, func, *args)
+ guard_op = self.lltrace.operations[self.current_index + 1]
+ assert guard_op.getopnum() == rop.GUARD_NOT_FORCED
+ self.force_guard_op = guard_op
call_args = support.cast_call_args_in_order(descr.ARGS, args)
- FUNC = lltype.FuncType(descr.ARGS, descr.RESULT)
- func_to_call = rffi.cast(lltype.Ptr(FUNC), func)
- result = func_to_call(*call_args)
+ #
+ func_adr = llmemory.cast_int_to_adr(func)
+ if hasattr(func_adr.ptr._obj, '_callable'):
+ # this is needed e.g. by test_fficall.test_guard_not_forced_fails,
+ # because to actually force the virtualref we need to llinterp the
+ # graph, not to directly execute the python function
+ result = self.cpu.maybe_on_top_of_llinterp(func, call_args,
descr.RESULT)
+ else:
+ FUNC = lltype.FuncType(descr.ARGS, descr.RESULT)
+ func_to_call = rffi.cast(lltype.Ptr(FUNC), func)
+ result = func_to_call(*call_args)
+ del self.force_guard_op
return support.cast_result(descr.RESULT, result)
def execute_call_assembler(self, descr, *args):
diff --git a/pypy/jit/metainterp/history.py b/pypy/jit/metainterp/history.py
--- a/pypy/jit/metainterp/history.py
+++ b/pypy/jit/metainterp/history.py
@@ -769,8 +769,8 @@
def show(self, errmsg=None):
"NOT_RPYTHON"
- from pypy.jit.metainterp.graphpage import display_loops
- display_loops([self], errmsg)
+ from pypy.jit.metainterp.graphpage import display_procedures
+ display_procedures([self], errmsg)
def check_consistency(self): # for testing
"NOT_RPYTHON"
diff --git a/pypy/jit/metainterp/test/test_fficall.py
b/pypy/jit/metainterp/test/test_fficall.py
--- a/pypy/jit/metainterp/test/test_fficall.py
+++ b/pypy/jit/metainterp/test/test_fficall.py
@@ -1,4 +1,5 @@
import py
+from pypy.rpython.annlowlevel import llhelper
from pypy.rpython.lltypesystem import lltype, rffi
from pypy.jit.metainterp.test.support import LLJitMixin
from pypy.rlib import jit
@@ -102,5 +103,74 @@
rffi.cast(rffi.SIGNEDCHAR, -42))
+ def test_guard_not_forced_fails(self):
+ FUNC = lltype.FuncType([lltype.Signed], lltype.Signed)
+
+ cif_description = get_description([types.slong], types.slong)
+ cif_description.exchange_args[0] = 16
+ cif_description.exchange_result = 32
+
+ ARRAY = lltype.Ptr(rffi.CArray(lltype.Signed))
+
+ @jit.dont_look_inside
+ def fn(n):
+ if n >= 50:
+ exctx.m = exctx.topframeref().n # forces the frame
+ return n*2
+
+ @jit.oopspec("libffi_call(cif_description,func_addr,exchange_buffer)")
+ def fake_call(cif_description, func_addr, exchange_buffer):
+ # read the args from the buffer
+ data_in = rffi.ptradd(exchange_buffer, 16)
+ n = rffi.cast(ARRAY, data_in)[0]
+ #
+ # logic of the function
+ func_ptr = rffi.cast(lltype.Ptr(FUNC), func_addr)
+ n = func_ptr(n)
+ #
+ # write the result to the buffer
+ data_out = rffi.ptradd(exchange_buffer, 32)
+ rffi.cast(ARRAY, data_out)[0] = n
+
+ def do_call(n):
+ func_ptr = llhelper(lltype.Ptr(FUNC), fn)
+ #func_addr = rffi.cast(rffi.VOIDP, func_ptr)
+ exbuf = lltype.malloc(rffi.CCHARP.TO, 48, flavor='raw', zero=True)
+ data_in = rffi.ptradd(exbuf, 16)
+ rffi.cast(ARRAY, data_in)[0] = n
+ fake_call(cif_description, func_ptr, exbuf)
+ data_out = rffi.ptradd(exbuf, 32)
+ res = rffi.cast(ARRAY, data_out)[0]
+ lltype.free(exbuf, flavor='raw')
+ return res
+
+ #
+ #
+ class XY:
+ pass
+ class ExCtx:
+ pass
+ exctx = ExCtx()
+ myjitdriver = jit.JitDriver(greens = [], reds = ['n'])
+ def f():
+ n = 0
+ while n < 100:
+ myjitdriver.jit_merge_point(n=n)
+ xy = XY()
+ xy.n = n
+ exctx.topframeref = vref = jit.virtual_ref(xy)
+ res = do_call(n) # this is equivalent of a cffi call which
+ # sometimes forces a frame
+ assert res == n*2
+ jit.virtual_ref_finish(vref, xy)
+ exctx.topframeref = jit.vref_None
+ n += 1
+ return n
+
+ assert f() == 100
+ res = self.meta_interp(f, [])
+ assert res == 100
+
+
class TestFfiCall(FfiCallTests, LLJitMixin):
pass
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit