Author: Maciej Fijalkowski <[email protected]>
Branch: jitframe-on-heap
Changeset: r60086:86e82d36c7c9
Date: 2013-01-15 19:22 +0200
http://bitbucket.org/pypy/pypy/changeset/86e82d36c7c9/
Log: Merge default and fix
diff --git a/pypy/jit/backend/test/test_random.py
b/pypy/jit/backend/test/test_random.py
--- a/pypy/jit/backend/test/test_random.py
+++ b/pypy/jit/backend/test/test_random.py
@@ -26,6 +26,8 @@
class OperationBuilder(object):
def __init__(self, cpu, loop, vars):
self.cpu = cpu
+ if not hasattr(cpu, '_faildescr_keepalive'):
+ cpu._faildescr_keepalive = []
self.fakemetainterp = FakeMetaInterp()
self.loop = loop
self.intvars = [box for box in vars if isinstance(box, BoxInt)]
@@ -206,6 +208,14 @@
if pytest.config.option.output:
s.close()
+ def getfaildescr(self, is_finish=False):
+ if is_finish:
+ descr = BasicFinalDescr()
+ else:
+ descr = BasicFailDescr()
+ self.cpu._faildescr_keepalive.append(descr)
+ return descr
+
class CannotProduceOperation(Exception):
pass
@@ -287,7 +297,7 @@
builder.intvars[:] = original_intvars
else:
op = ResOperation(rop.GUARD_NO_OVERFLOW, [], None)
- op.setdescr(BasicFailDescr())
+ op.setdescr(builder.getfaildescr())
op.setfailargs(fail_subset)
builder.loop.operations.append(op)
@@ -357,7 +367,7 @@
def produce_into(self, builder, r):
op, passing = self.gen_guard(builder, r)
builder.loop.operations.append(op)
- op.setdescr(BasicFailDescr())
+ op.setdescr(builder.getfaildescr())
op.setfailargs(builder.subset_of_intvars(r))
if not passing:
builder.should_fail_by = op
@@ -618,8 +628,9 @@
if v not in used_later:
endvars.append(v)
r.shuffle(endvars)
+ endvars = endvars[:1]
loop.operations.append(ResOperation(rop.FINISH, endvars, None,
- descr=BasicFinalDescr()))
+
descr=builder.getfaildescr(is_finish=True)))
if builder.should_fail_by:
self.should_fail_by = builder.should_fail_by
self.guard_op = builder.guard_op
@@ -712,7 +723,7 @@
else:
op = ResOperation(rop.GUARD_EXCEPTION, [guard_op._exc_box],
BoxPtr())
- op.setdescr(BasicFailDescr())
+ op.setdescr(self.builder.getfaildescr())
op.setfailargs([])
return op
diff --git a/pypy/jit/backend/x86/assembler.py
b/pypy/jit/backend/x86/assembler.py
--- a/pypy/jit/backend/x86/assembler.py
+++ b/pypy/jit/backend/x86/assembler.py
@@ -675,8 +675,13 @@
self.mc.CMP_bi(ofs - base_ofs, 0xffffff)
stack_check_cmp_ofs = self.mc.get_relative_pos() - 4
assert not IS_X86_32
- self.mc.J_il8(rx86.Conditions['G'], 9)
+ self.mc.J_il8(rx86.Conditions['G'], 0)
+ jg_location = self.mc.get_relative_pos()
self.mc.CALL(imm(self._stack_check_failure))
+ # patch the JG above
+ offset = self.mc.get_relative_pos() - jg_location
+ assert 0 < offset <= 127
+ self.mc.overwrite(jg_location-1, chr(offset))
return stack_check_cmp_ofs
def _patch_stackadjust(self, adr, allocated_depth):
@@ -1860,9 +1865,9 @@
else:
v = gpr_reg_mgr_cls.all_reg_indexes[loc.value]
positions[i] = v * WORD
+ # write down the positions of locs
guardtok.faildescr.rd_locs = positions
- # write fail_index too
- # for testing the decoding, write a final byte 0xCC
+ # write down the GC pattern
return startpos
def rebuild_faillocs_from_descr(self, descr, inputargs):
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
@@ -106,7 +106,7 @@
class TestFfiCall(FfiCallTests, LLJitMixin):
- def test_jit_fii_vref(self):
+ def test_jit_ffi_vref(self):
py.test.skip("unsupported so far")
from pypy.rlib import clibffi
from pypy.rlib.jit_libffi import jit_ffi_prep_cif, jit_ffi_call
@@ -138,9 +138,10 @@
res = exb[3]
lltype.free(exb, flavor='raw')
#
- lltype.free(atypes, flavor='raw')
return res
#
res = self.interp_operations(f, [])
lltype.free(cd, flavor='raw')
assert res == math.sin(1.23)
+
+ lltype.free(atypes, flavor='raw')
diff --git a/pypy/jit/metainterp/test/test_warmspot.py
b/pypy/jit/metainterp/test/test_warmspot.py
--- a/pypy/jit/metainterp/test/test_warmspot.py
+++ b/pypy/jit/metainterp/test/test_warmspot.py
@@ -1,6 +1,6 @@
import py
from pypy.jit.metainterp.warmspot import get_stats
-from pypy.rlib.jit import JitDriver, set_param, unroll_safe
+from pypy.rlib.jit import JitDriver, set_param, unroll_safe, jit_callback
from pypy.jit.backend.llgraph import runner
from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin
@@ -537,41 +537,21 @@
def test_callback_jit_merge_point(self):
- from pypy.rlib.objectmodel import register_around_callback_hook
- from pypy.rpython.lltypesystem import lltype, rffi
- from pypy.translator.tool.cbuild import ExternalCompilationInfo
-
- callback_jit_driver = JitDriver(greens = ['name'], reds = 'auto')
-
- def callback_merge_point(name):
- callback_jit_driver.jit_merge_point(name=name)
-
- @callback_jit_driver.inline(callback_merge_point)
- def callback_hook(name):
- pass
-
+ @jit_callback("testing")
def callback(a, b):
if a > b:
return 1
return -1
- CB_TP = rffi.CCallback([lltype.Signed, lltype.Signed], lltype.Signed)
- eci = ExternalCompilationInfo(includes=['stdlib.h'])
- qsort = rffi.llexternal('qsort',
- [rffi.VOIDP, lltype.Signed, lltype.Signed,
- CB_TP], lltype.Void, compilation_info=eci)
- ARR = rffi.CArray(lltype.Signed)
+ def main():
+ total = 0
+ for i in range(10):
+ total += callback(i, 2)
+ return total
- def main():
- register_around_callback_hook(callback_hook)
- raw = lltype.malloc(ARR, 10, flavor='raw')
- for i in range(10):
- raw[i] = 10 - i
- qsort(raw, 10, rffi.sizeof(lltype.Signed), callback)
- lltype.free(raw, flavor='raw')
-
- self.meta_interp(main, [])
- self.check_trace_count(1)
+ res = self.meta_interp(main, [])
+ assert res == 7 - 3
+ self.check_trace_count(2)
class TestLLWarmspot(WarmspotTests, LLJitMixin):
diff --git a/pypy/jit/metainterp/warmspot.py b/pypy/jit/metainterp/warmspot.py
--- a/pypy/jit/metainterp/warmspot.py
+++ b/pypy/jit/metainterp/warmspot.py
@@ -360,13 +360,7 @@
jd._jit_merge_point_in = graph
args = op.args[2:]
s_binding = self.translator.annotator.binding
- if op.args[1].value.autoreds:
- # _portal_args_s is used only by _make_hook_graph, but for now we
- # declare the various set_jitcell_at, get_printable_location,
- # etc. as incompatible with autoreds
- jd._portal_args_s = None
- else:
- jd._portal_args_s = [s_binding(v) for v in args]
+ jd._portal_args_s = [s_binding(v) for v in args]
graph = copygraph(graph)
[jmpp] = find_jit_merge_points([graph])
graph.startblock = support.split_before_jit_merge_point(*jmpp)
@@ -614,9 +608,10 @@
if func is None:
return None
#
- assert not jitdriver_sd.jitdriver.autoreds, (
- "reds='auto' is not compatible with JitDriver hooks such as "
- "{get,set}_jitcell_at, get_printable_location, confirm_enter_jit,
etc.")
+ if not onlygreens:
+ assert not jitdriver_sd.jitdriver.autoreds, (
+ "reds='auto' is not compatible with JitDriver hooks such as "
+ "confirm_enter_jit")
extra_args_s = []
if s_first_arg is not None:
extra_args_s.append(s_first_arg)
diff --git a/pypy/module/_cffi_backend/ccallback.py
b/pypy/module/_cffi_backend/ccallback.py
--- a/pypy/module/_cffi_backend/ccallback.py
+++ b/pypy/module/_cffi_backend/ccallback.py
@@ -152,6 +152,7 @@
STDERR = 2
[email protected]_callback("CFFI")
def invoke_callback(ffi_cif, ll_res, ll_args, ll_userdata):
""" Callback specification.
ffi_cif - something ffi specific, don't care
diff --git a/pypy/module/pyexpat/interp_pyexpat.py
b/pypy/module/pyexpat/interp_pyexpat.py
--- a/pypy/module/pyexpat/interp_pyexpat.py
+++ b/pypy/module/pyexpat/interp_pyexpat.py
@@ -2,7 +2,7 @@
from pypy.interpreter.typedef import TypeDef, GetSetProperty
from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault
from pypy.interpreter.error import OperationError
-from pypy.rlib import rgc
+from pypy.rlib import rgc, jit
from pypy.rpython.lltypesystem import rffi, lltype
from pypy.rpython.tool import rffi_platform
from pypy.translator.tool.cbuild import ExternalCompilationInfo
@@ -288,6 +288,7 @@
post_code = ''
src = py.code.Source("""
+ @jit.jit_callback('XML:%(name)s')
def %(name)s_callback(%(first_arg)s, %(args)s):
id = rffi.cast(lltype.Signed, %(ll_id)s)
userdata = global_storage.get_object(id)
diff --git a/pypy/module/pypyjit/interp_jit.py
b/pypy/module/pypyjit/interp_jit.py
--- a/pypy/module/pypyjit/interp_jit.py
+++ b/pypy/module/pypyjit/interp_jit.py
@@ -6,7 +6,7 @@
from pypy.tool.pairtype import extendabletype
from pypy.rlib.rarithmetic import r_uint, intmask
from pypy.rlib.jit import JitDriver, hint, we_are_jitted, dont_look_inside
-from pypy.rlib import jit, objectmodel
+from pypy.rlib import jit
from pypy.rlib.jit import current_trace_length, unroll_parameters
import pypy.interpreter.pyopcode # for side-effects
from pypy.interpreter.error import OperationError, operationerrfmt
@@ -97,15 +97,6 @@
is_being_profiled=self.is_being_profiled)
return jumpto
-callback_jit_driver = JitDriver(greens = ['name'], reds = 'auto')
-
-def callback_merge_point(name):
- callback_jit_driver.jit_merge_point(name=name)
-
-@callback_jit_driver.inline(callback_merge_point)
-def callback_hook(name):
- pass
-
def _get_adapted_tick_counter():
# Normally, the tick counter is decremented by 100 for every
# Python opcode. Here, to better support JIT compilation of
diff --git a/pypy/module/signal/interp_signal.py
b/pypy/module/signal/interp_signal.py
--- a/pypy/module/signal/interp_signal.py
+++ b/pypy/module/signal/interp_signal.py
@@ -40,6 +40,7 @@
includes = ['stdlib.h', 'src/signals.h']
if sys.platform != 'win32':
includes.append('sys/time.h')
+WIN32 = sys.platform == 'win32'
cdir = py.path.local(autopath.pypydir).join('translator', 'c')
@@ -236,7 +237,10 @@
None -- if an unknown handler is in effect (XXX UNIMPLEMENTED)
anything else -- the callable Python object used as a handler
"""
- check_signum_in_range(space, signum)
+ if WIN32:
+ check_signum_exists(space, signum)
+ else:
+ check_signum_in_range(space, signum)
action = space.check_signal_action
if signum in action.handlers_w:
return action.handlers_w[signum]
diff --git a/pypy/module/signal/test/test_signal.py
b/pypy/module/signal/test/test_signal.py
--- a/pypy/module/signal/test/test_signal.py
+++ b/pypy/module/signal/test/test_signal.py
@@ -55,7 +55,7 @@
skip("requires os.kill() and os.getpid()")
signal = self.signal # the signal module to test
if not hasattr(signal, 'SIGUSR1'):
- py.test.skip("requires SIGUSR1 in signal")
+ skip("requires SIGUSR1 in signal")
signum = signal.SIGUSR1
received = []
@@ -156,6 +156,7 @@
import sys
if sys.platform == 'win32':
raises(ValueError, signal, 42, lambda *args: None)
+ raises(ValueError, signal, 7, lambda *args: None)
else:
signal(42, lambda *args: None)
signal(42, SIG_DFL)
diff --git a/pypy/module/thread/os_thread.py b/pypy/module/thread/os_thread.py
--- a/pypy/module/thread/os_thread.py
+++ b/pypy/module/thread/os_thread.py
@@ -2,6 +2,7 @@
Thread support based on OS-level threads.
"""
+import os
from pypy.module.thread import ll_thread as thread
from pypy.module.thread.error import wrap_thread_error
from pypy.interpreter.error import OperationError, operationerrfmt
@@ -91,14 +92,18 @@
# run!
try:
bootstrapper.run(space, w_callable, args)
- finally:
- bootstrapper.nbthreads -= 1
- # clean up space.threadlocals to remove the ExecutionContext
- # entry corresponding to the current thread
+ # done
+ except Exception, e:
+ # oups! last-level attempt to recover.
try:
- space.threadlocals.leave_thread(space)
- finally:
- thread.gc_thread_die()
+ STDERR = 2
+ os.write(STDERR, "Thread exited with ")
+ os.write(STDERR, str(e))
+ os.write(STDERR, "\n")
+ except OSError:
+ pass
+ bootstrapper.nbthreads -= 1
+ thread.gc_thread_die()
bootstrap = staticmethod(bootstrap)
def acquire(space, w_callable, args):
@@ -129,6 +134,9 @@
where = 'thread %d started by ' % ident
e.write_unraisable(space, where, w_callable)
e.clear(space)
+ # clean up space.threadlocals to remove the ExecutionContext
+ # entry corresponding to the current thread
+ space.threadlocals.leave_thread(space)
run = staticmethod(run)
bootstrapper = Bootstrapper()
diff --git a/pypy/module/thread/test/test_gil.py
b/pypy/module/thread/test/test_gil.py
--- a/pypy/module/thread/test/test_gil.py
+++ b/pypy/module/thread/test/test_gil.py
@@ -61,8 +61,9 @@
def bootstrap():
try:
runme()
- finally:
- thread.gc_thread_die()
+ except Exception, e:
+ assert 0
+ thread.gc_thread_die()
def f():
state.data = []
state.datalen1 = 0
diff --git a/pypy/rlib/clibffi.py b/pypy/rlib/clibffi.py
--- a/pypy/rlib/clibffi.py
+++ b/pypy/rlib/clibffi.py
@@ -421,6 +421,7 @@
hints={'callback':True}))
[email protected]_callback("CLIBFFI")
def ll_callback(ffi_cif, ll_res, ll_args, ll_userdata):
""" Callback specification.
ffi_cif - something ffi specific, don't care
diff --git a/pypy/rlib/jit.py b/pypy/rlib/jit.py
--- a/pypy/rlib/jit.py
+++ b/pypy/rlib/jit.py
@@ -302,6 +302,32 @@
pass
+def jit_callback(name):
+ """Use as a decorator for C callback functions, to insert a
+ jitdriver.jit_merge_point() at the start. Only for callbacks
+ that typically invoke more app-level Python code.
+ """
+ def decorate(func):
+ from pypy.tool.sourcetools import compile2
+ #
+ def get_printable_location():
+ return name
+ jitdriver = JitDriver(get_printable_location=get_printable_location,
+ greens=[], reds='auto', name=name)
+ #
+ args = ','.join(['a%d' % i for i in range(func.func_code.co_argcount)])
+ source = """def callback_with_jitdriver(%(args)s):
+ jitdriver.jit_merge_point()
+ return real_callback(%(args)s)""" % locals()
+ miniglobals = {
+ 'jitdriver': jitdriver,
+ 'real_callback': func,
+ }
+ exec compile2(source) in miniglobals
+ return miniglobals['callback_with_jitdriver']
+ return decorate
+
+
# ____________________________________________________________
# VRefs
@@ -458,9 +484,8 @@
self.autoreds = True
self.reds = []
self.numreds = None # see warmspot.autodetect_jit_markers_redvars
- for hook in (get_jitcell_at, set_jitcell_at,
get_printable_location,
- confirm_enter_jit):
- assert hook is None, "reds='auto' is not compatible with
JitDriver hooks"
+ assert confirm_enter_jit is None, (
+ "reds='auto' is not compatible with confirm_enter_jit")
else:
if reds is not None:
self.reds = reds
diff --git a/pypy/rlib/objectmodel.py b/pypy/rlib/objectmodel.py
--- a/pypy/rlib/objectmodel.py
+++ b/pypy/rlib/objectmodel.py
@@ -595,16 +595,6 @@
llhelper(rffi.AroundFnPtr, before)
llhelper(rffi.AroundFnPtr, after)
-def register_around_callback_hook(hook):
- """ Register a hook that's called before a callback from C calls RPython.
- Primary usage is for JIT to have 'started from' hook.
- """
- from pypy.rpython.lltypesystem import rffi
- from pypy.rpython.annlowlevel import llhelper
-
- rffi.aroundstate.callback_hook = hook
- llhelper(rffi.CallbackHookPtr, hook)
-
def is_in_callback():
from pypy.rpython.lltypesystem import rffi
return rffi.stackcounter.stacks_counter > 1
diff --git a/pypy/rpython/lltypesystem/rffi.py
b/pypy/rpython/lltypesystem/rffi.py
--- a/pypy/rpython/lltypesystem/rffi.py
+++ b/pypy/rpython/lltypesystem/rffi.py
@@ -1,6 +1,6 @@
import py
from pypy.annotation import model as annmodel
-from pypy.rpython.lltypesystem import lltype, rstr
+from pypy.rpython.lltypesystem import lltype
from pypy.rpython.lltypesystem import ll2ctypes
from pypy.rpython.lltypesystem.llmemory import cast_ptr_to_adr
from pypy.rpython.lltypesystem.llmemory import itemoffsetof, raw_memcopy
@@ -13,7 +13,7 @@
from pypy.rlib.unroll import unrolling_iterable
from pypy.rpython.tool.rfficache import platform, sizeof_c_type
from pypy.translator.tool.cbuild import ExternalCompilationInfo
-from pypy.rpython.annlowlevel import llhelper, llstr
+from pypy.rpython.annlowlevel import llhelper
from pypy.rlib.objectmodel import we_are_translated
from pypy.rlib.rstring import StringBuilder, UnicodeBuilder, assert_str0
from pypy.rlib import jit
@@ -279,17 +279,8 @@
callable_name = getattr(callable, '__name__', '?')
if callbackholder is not None:
callbackholder.callbacks[callable] = True
- callable_name_descr = str(callable).replace('"', '\\"')
args = ', '.join(['a%d' % i for i in range(len(TP.TO.ARGS))])
source = py.code.Source(r"""
- def inner_wrapper(%(args)s):
- if aroundstate is not None:
- callback_hook = aroundstate.callback_hook
- if callback_hook:
- callback_hook(llstr("%(callable_name_descr)s"))
- return callable(%(args)s)
- inner_wrapper._never_inline_ = True
-
def wrapper(%(args)s): # no *args - no GIL for mallocing the tuple
llop.gc_stack_bottom(lltype.Void) # marker for trackgcroot.py
if aroundstate is not None:
@@ -299,7 +290,7 @@
# from now on we hold the GIL
stackcounter.stacks_counter += 1
try:
- result = inner_wrapper(%(args)s)
+ result = callable(%(args)s)
except Exception, e:
os.write(2,
"Warning: uncaught exception in callback: %%s %%s\n" %%
@@ -321,7 +312,6 @@
miniglobals = locals().copy()
miniglobals['Exception'] = Exception
miniglobals['os'] = os
- miniglobals['llstr'] = llstr
miniglobals['we_are_translated'] = we_are_translated
miniglobals['stackcounter'] = stackcounter
exec source.compile() in miniglobals
@@ -329,11 +319,8 @@
_make_wrapper_for._annspecialcase_ = 'specialize:memo'
AroundFnPtr = lltype.Ptr(lltype.FuncType([], lltype.Void))
-CallbackHookPtr = lltype.Ptr(lltype.FuncType([lltype.Ptr(rstr.STR)],
lltype.Void))
class AroundState:
- callback_hook = None
-
def _cleanup_(self):
self.before = None # or a regular RPython function
self.after = None # or a regular RPython function
diff --git a/pypy/rpython/memory/gctransform/framework.py
b/pypy/rpython/memory/gctransform/framework.py
--- a/pypy/rpython/memory/gctransform/framework.py
+++ b/pypy/rpython/memory/gctransform/framework.py
@@ -968,6 +968,7 @@
assert self.translator.config.translation.thread
if hasattr(self.root_walker, 'thread_run_ptr'):
livevars = self.push_roots(hop)
+ assert not livevars, "live GC var around %s!" % (hop.spaceop,)
hop.genop("direct_call", [self.root_walker.thread_run_ptr])
self.pop_roots(hop, livevars)
@@ -982,6 +983,7 @@
assert self.translator.config.translation.thread
if hasattr(self.root_walker, 'thread_die_ptr'):
livevars = self.push_roots(hop)
+ assert not livevars, "live GC var around %s!" % (hop.spaceop,)
hop.genop("direct_call", [self.root_walker.thread_die_ptr])
self.pop_roots(hop, livevars)
diff --git a/pypy/rpython/memory/gctransform/shadowstack.py
b/pypy/rpython/memory/gctransform/shadowstack.py
--- a/pypy/rpython/memory/gctransform/shadowstack.py
+++ b/pypy/rpython/memory/gctransform/shadowstack.py
@@ -326,6 +326,8 @@
self.gcdata.root_stack_top = llmemory.NULL # to detect missing restore
def forget_current_state(self):
+ ll_assert(self.gcdata.root_stack_base == self.gcdata.root_stack_top,
+ "forget_current_state: shadowstack not empty!")
if self.unused_full_stack:
llmemory.raw_free(self.unused_full_stack)
self.unused_full_stack = self.gcdata.root_stack_base
diff --git a/pypy/translator/goal/targetpypystandalone.py
b/pypy/translator/goal/targetpypystandalone.py
--- a/pypy/translator/goal/targetpypystandalone.py
+++ b/pypy/translator/goal/targetpypystandalone.py
@@ -28,11 +28,6 @@
w_call_startup_gateway = space.wrap(gateway.interp2app(call_startup))
withjit = space.config.objspace.usemodules.pypyjit
- if withjit:
- from pypy.module.pypyjit.interp_jit import callback_hook
- from pypy.rlib import objectmodel
- objectmodel.register_around_callback_hook(callback_hook)
-
def entry_point(argv):
if withjit:
from pypy.jit.backend.hlinfo import highleveljitinfo
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit