Author: Armin Rigo <[email protected]>
Branch: stmgc-c7
Changeset: r70768:a76fc199431f
Date: 2014-04-19 13:48 +0200
http://bitbucket.org/pypy/pypy/changeset/a76fc199431f/
Log: in-progress
diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -44,9 +44,19 @@
return func_with_new_name(opimpl, "opcode_impl_for_%s" % operationname)
-stmonly_jitdriver = jit.JitDriver(greens=[], reds=['next_instr', 'ec',
- 'self', 'co_code'],
- stm_do_transaction_breaks=True)
+# ____________________________________________________________
+
+class PyPyJitDriver(jit.JitDriver):
+ reds = ['frame', 'ec']
+ greens = ['next_instr', 'is_being_profiled', 'pycode']
+ virtualizables = ['frame']
+ stm_do_transaction_breaks = True
+ is_main_for_pypy = True # XXX temporary: turning 'greens' into a string
+ # is hard-coded in C code. Don't change 'greens'
+
+stmonly_jitdriver = PyPyJitDriver()
+
+# ____________________________________________________________
opcodedesc = bytecode_spec.opcodedesc
HAVE_ARGUMENT = bytecode_spec.HAVE_ARGUMENT
@@ -61,6 +71,7 @@
# For the sequel, force 'next_instr' to be unsigned for performance
next_instr = r_uint(next_instr)
co_code = pycode.co_code
+ rstm.push_marker(intmask(next_instr) * 2 + 1, pycode)
try:
while True:
@@ -71,8 +82,11 @@
self=self, co_code=co_code,
next_instr=next_instr, ec=ec)
next_instr = self.handle_bytecode(co_code, next_instr, ec)
+ rstm.update_marker_num(intmask(next_instr) * 2 + 1)
except ExitFrame:
return self.popvalue()
+ finally:
+ rstm.pop_marker()
def handle_bytecode(self, co_code, next_instr, ec):
try:
@@ -467,6 +481,8 @@
opcodedesc.LOAD_FAST.index):
return next_instr
+ rstm.update_marker_num(intmask(next_instr) * 2 + 1)
+
@jit.unroll_safe
def unrollstack(self, unroller_kind):
while self.blockstack_non_empty():
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
@@ -12,6 +12,7 @@
from pypy.interpreter.pycode import CO_GENERATOR
from pypy.interpreter.pyframe import PyFrame
from pypy.interpreter.pyopcode import ExitFrame, Yield
+from pypy.interpreter.pyopcode import PyPyJitDriver
from opcode import opmap
@@ -36,16 +37,10 @@
def should_unroll_one_iteration(next_instr, is_being_profiled, bytecode):
return (bytecode.co_flags & CO_GENERATOR) != 0
-class PyPyJitDriver(JitDriver):
- reds = ['frame', 'ec']
- greens = ['next_instr', 'is_being_profiled', 'pycode']
- virtualizables = ['frame']
-
pypyjitdriver = PyPyJitDriver(get_printable_location = get_printable_location,
should_unroll_one_iteration =
should_unroll_one_iteration,
- name='pypyjit',
- stm_do_transaction_breaks=True)
+ name='pypyjit')
class __extend__(PyFrame):
diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py
--- a/rpython/rlib/jit.py
+++ b/rpython/rlib/jit.py
@@ -490,7 +490,7 @@
get_printable_location=None, confirm_enter_jit=None,
can_never_inline=None, should_unroll_one_iteration=None,
name='jitdriver', check_untranslated=True,
- stm_do_transaction_breaks=False):
+ stm_do_transaction_breaks=None):
if greens is not None:
self.greens = greens
self.name = name
@@ -526,7 +526,8 @@
self.can_never_inline = can_never_inline
self.should_unroll_one_iteration = should_unroll_one_iteration
self.check_untranslated = check_untranslated
- self.stm_do_transaction_breaks = stm_do_transaction_breaks
+ if stm_do_transaction_breaks is not None:
+ self.stm_do_transaction_breaks = stm_do_transaction_breaks
def _freeze_(self):
return True
diff --git a/rpython/rlib/rstm.py b/rpython/rlib/rstm.py
--- a/rpython/rlib/rstm.py
+++ b/rpython/rlib/rstm.py
@@ -122,6 +122,16 @@
invoke_around_extcall(before_external_call, after_external_call,
enter_callback_call, leave_callback_call)
[email protected](1)
+def push_marker(odd_num, object):
+ llop.stm_push_marker(lltype.Void, odd_num, object)
+
+def update_marker_num(odd_num):
+ llop.stm_update_marker_num(lltype.Void, odd_num)
+
+def pop_marker():
+ llop.stm_pop_marker(lltype.Void)
+
# ____________________________________________________________
def make_perform_transaction(func, CONTAINERP):
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
@@ -451,6 +451,12 @@
'stm_ignored_start': LLOp(canrun=True),
'stm_ignored_stop': LLOp(canrun=True),
+ 'stm_push_marker': LLOp(canrun=True),
+ 'stm_update_marker_num': LLOp(canrun=True),
+ 'stm_pop_marker': LLOp(canrun=True),
+ 'stm_expand_marker': LLOp(),
+ 'stm_setup_expand_marker_for_pypy': LLOp(),
+
## 'stm_allocate_nonmovable_int_adr': LLOp(sideeffects=False,
canmallocgc=True),
## 'stm_become_inevitable': LLOp(canmallocgc=True),
## 'stm_stop_all_other_threads': LLOp(canmallocgc=True),
diff --git a/rpython/rtyper/lltypesystem/opimpl.py
b/rpython/rtyper/lltypesystem/opimpl.py
--- a/rpython/rtyper/lltypesystem/opimpl.py
+++ b/rpython/rtyper/lltypesystem/opimpl.py
@@ -680,8 +680,14 @@
def op_stm_ignored_stop():
pass
-def op_stm_ptr_eq(x, y):
- return op_ptr_eq(x, y)
+def op_stm_push_marker(odd_num, object):
+ pass
+
+def op_stm_update_marker_num(odd_num):
+ pass
+
+def op_stm_pop_marker():
+ pass
def op_stm_get_tid(x):
raise NotImplementedError
diff --git a/rpython/translator/c/genc.py b/rpython/translator/c/genc.py
--- a/rpython/translator/c/genc.py
+++ b/rpython/translator/c/genc.py
@@ -881,46 +881,10 @@
print >> f, '\t%d,' % (i,)
print >> f, '\t-1'
print >> f, '};'
- print >> f, '''
-void pypy_stm_setup_prebuilt(void)
-{
- object_t **pp = rpy_prebuilt;
- long *ph = rpy_prebuilt_hashes;
- int i = 0;
- int *wri = weakref_indices;
- for ( ; *pp; pp++, ph++, i++) {
- if (i == *wri) {
- *pp = stm_setup_prebuilt_weakref(*pp);
- wri++;
- }
- else {
- *pp = stm_setup_prebuilt(*pp);
- }
- stm_set_prebuilt_identityhash(*pp, *ph);
- }
-
- object_t ***cur = (object_t ***)
- pypy_g_rpython_memory_gctypelayout_GCData.gcd_inst_static_root_start;
- object_t ***end = (object_t ***)
- pypy_g_rpython_memory_gctypelayout_GCData.gcd_inst_static_root_nongcend;
- for ( ; cur != end; cur++) {
- **cur = stm_setup_prebuilt(**cur);
- }
-}
-
-void pypy_stm_register_thread_local(void)
-{
- stm_register_thread_local(&stm_thread_local);
- stm_thread_local.mem_clear_on_abort = (char *)&pypy_g_ExcData;
- stm_thread_local.mem_bytes_to_clear_on_abort = sizeof(pypy_g_ExcData);
-}
-
-void pypy_stm_unregister_thread_local(void)
-{
- stm_flush_timing(&stm_thread_local, 1); // XXX temporary
- stm_unregister_thread_local(&stm_thread_local);
-}
-'''
+ print >> f
+ print >> f, '#include "preimpl.h"'
+ print >> f, '#include "src/rtyper.h"'
+ print >> f, '#include "src_stm/extracode.h"'
def commondefs(defines):
from rpython.rlib.rarithmetic import LONG_BIT, LONGLONG_BIT
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
@@ -207,126 +207,30 @@
return '%s = (%s)&stm_thread_local.shadowstack;' % (
result, cdecl(funcgen.lltypename(op.result), ''))
+def stm_push_marker(funcgen, op):
+ arg0 = funcgen.expr(op.args[0])
+ arg1 = funcgen.expr(op.args[1])
+ return 'STM_PUSH_MARKER(stm_thread_local, %s, %s);' % (arg0, arg1)
-##def stm_initialize(funcgen, op):
-## return '''stm_initialize();
-## stm_clear_on_abort(&pypy_g_ExcData, sizeof(pypy_g_ExcData));
-## '''
+def stm_update_marker_num(funcgen, op):
+ arg0 = funcgen.expr(op.args[0])
+ return 'STM_UPDATE_MARKER_NUM(stm_thread_local, %s);' % (arg0,)
-##def stm_finalize(funcgen, op):
-## return 'stm_finalize();'
+def stm_pop_marker(funcgen, op):
+ return 'STM_POP_MARKER(stm_thread_local);'
-##def stm_barrier(funcgen, op):
-## category_change = op.args[0].value
-## # XXX: how to unify the stm_barrier llop generation in
-## # writebarrier.py and threadlocalref.py?
-## if isinstance(category_change, str):
-## frm, middle, to = category_change
-## else: # rstr
-## frm, middle, to = (category_change.chars[0],
-## category_change.chars[1],
-## category_change.chars[2])
-## assert middle == '2'
-## assert frm < to
-## if to == 'W':
-## if frm >= 'V':
-## funcname = 'stm_repeat_write_barrier'
-## else:
-## funcname = 'stm_write_barrier'
-## elif to == 'V':
-## funcname = 'stm_write_barrier_noptr'
-## elif to == 'R':
-## if frm >= 'Q':
-## funcname = 'stm_repeat_read_barrier'
-## else:
-## funcname = 'stm_read_barrier'
-## elif to == 'I':
-## funcname = 'stm_immut_read_barrier'
-## else:
-## raise AssertionError(category_change)
-## assert op.args[1].concretetype == op.result.concretetype
-## arg = funcgen.expr(op.args[1])
-## result = funcgen.expr(op.result)
-## return '%s = (%s)%s((gcptr)%s);' % (
-## result, cdecl(funcgen.lltypename(op.result), ''),
-## funcname, arg)
+def stm_expand_marker(funcgen, op):
+ result = funcgen.expr(op.result)
+ return '%s = _stm_expand_marker();' % (result,)
-##def stm_ptr_eq(funcgen, op):
-## args = [funcgen.expr(v) for v in op.args]
-## result = funcgen.expr(op.result)
-## # check for prebuilt arguments
-## for i, j in [(0, 1), (1, 0)]:
-## if isinstance(op.args[j], Constant):
-## if op.args[j].value: # non-NULL
-## return ('%s = stm_pointer_equal_prebuilt((gcptr)%s,
(gcptr)%s);'
-## % (result, args[i], args[j]))
-## else:
-## # this case might be unreachable, but better safe than sorry
-## return '%s = (%s == NULL);' % (result, args[i])
-## #
-## return '%s = stm_pointer_equal((gcptr)%s, (gcptr)%s);' % (
-## result, args[0], args[1])
-
-##def stm_stop_all_other_threads(funcgen, op):
-## return 'stm_stop_all_other_threads();'
-
-##def stm_partial_commit_and_resume_other_threads(funcgen, op):
-## return 'stm_partial_commit_and_resume_other_threads();'
-
-##def stm_get_adr_of_nursery_current(funcgen, op):
-## result = funcgen.expr(op.result)
-## return '%s = (%s)&stm_nursery_current;' % (
-## result, cdecl(funcgen.lltypename(op.result), ''))
-
-##def stm_get_adr_of_nursery_nextlimit(funcgen, op):
-## result = funcgen.expr(op.result)
-## return '%s = (%s)&stm_nursery_nextlimit;' % (
-## result, cdecl(funcgen.lltypename(op.result), ''))
-
-##def stm_get_adr_of_active(funcgen, op):
-## result = funcgen.expr(op.result)
-## return '%s = (%s)&stm_active;' % (
-## result, cdecl(funcgen.lltypename(op.result), ''))
-
-##def stm_get_adr_of_private_rev_num(funcgen, op):
-## result = funcgen.expr(op.result)
-## return '%s = (%s)&stm_private_rev_num;' % (
-## result, cdecl(funcgen.lltypename(op.result), ''))
-
-##def stm_get_adr_of_read_barrier_cache(funcgen, op):
-## result = funcgen.expr(op.result)
-## return '%s = (%s)&stm_read_barrier_cache;' % (
-## 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_nonmovable_int_adr(funcgen, op):
-## arg0 = funcgen.expr(op.args[0])
-## result = funcgen.expr(op.result)
-## return '%s = stm_allocate_public_integer_address(%s);' % (result, arg0)
-
-##def stm_get_tid(funcgen, op):
-## arg0 = funcgen.expr(op.args[0])
-## result = funcgen.expr(op.result)
-## return '%s = ((struct rpyobj_s*)%s)->tid;' % (result, arg0)
-
-##def stm_enter_callback_call(funcgen, op):
-## result = funcgen.expr(op.result)
-## return '%s = stm_enter_callback_call();' % (result,)
-
-##def stm_leave_callback_call(funcgen, op):
-## arg0 = funcgen.expr(op.args[0])
-## return 'stm_leave_callback_call(%s);' % (arg0,)
-
-##def stm_minor_collect(funcgen, op):
-## return 'stm_minor_collect();'
-
-##def stm_major_collect(funcgen, op):
-## return 'stm_major_collect();'
+def stm_setup_expand_marker_for_pypy(funcgen, op):
+ # hack hack hack
+ node = funcgen.db.gettypedefnode(op.args[0].concretetype.TO)
+ typename = funcgen.db.gettype(op.args[0].concretetype.TO)
+ names = [''.join(arg.value.chars) for arg in op.args[1:]]
+ names = [node.c_struct_field_name('inst_' + name) for name in names]
+ offsets = ['offsetof(%s, %s)' % (cdecl(typename, ''), name)
+ for name in names]
+ assert len(offsets) == 4
+ return 'pypy_stm_setup_expand_marker(%s, %s, %s, %s);' % (
+ offsets[0], offsets[1], offsets[2], offsets[3])
diff --git a/rpython/translator/stm/src_stm/extracode.h
b/rpython/translator/stm/src_stm/extracode.h
new file mode 100644
--- /dev/null
+++ b/rpython/translator/stm/src_stm/extracode.h
@@ -0,0 +1,115 @@
+
+void pypy_stm_setup_prebuilt(void)
+{
+ object_t **pp = rpy_prebuilt;
+ long *ph = rpy_prebuilt_hashes;
+ int i = 0;
+ int *wri = weakref_indices;
+ for ( ; *pp; pp++, ph++, i++) {
+ if (i == *wri) {
+ *pp = stm_setup_prebuilt_weakref(*pp);
+ wri++;
+ }
+ else {
+ *pp = stm_setup_prebuilt(*pp);
+ }
+ stm_set_prebuilt_identityhash(*pp, *ph);
+ }
+
+ object_t ***cur = (object_t ***)
+ pypy_g_rpython_memory_gctypelayout_GCData.gcd_inst_static_root_start;
+ object_t ***end = (object_t ***)
+ pypy_g_rpython_memory_gctypelayout_GCData.gcd_inst_static_root_nongcend;
+ for ( ; cur != end; cur++) {
+ **cur = stm_setup_prebuilt(**cur);
+ }
+}
+
+void pypy_stm_register_thread_local(void)
+{
+ stm_register_thread_local(&stm_thread_local);
+ stm_thread_local.mem_clear_on_abort = (char *)&pypy_g_ExcData;
+ stm_thread_local.mem_bytes_to_clear_on_abort = sizeof(pypy_g_ExcData);
+}
+
+void pypy_stm_unregister_thread_local(void)
+{
+ stm_flush_timing(&stm_thread_local, 1); // XXX temporary
+ stm_unregister_thread_local(&stm_thread_local);
+}
+
+
+/************************************************************/
+/*** HACK: hard-coded logic to expand the marker into ***/
+/*** a string, suitable for running in PyPy ***/
+
+static long g_co_filename_ofs;
+static long g_co_name_ofs;
+static long g_co_firstlineno_ofs;
+static long g_co_lnotab_ofs;
+
+static char *_RPyString_AsString_Real(RPyString *obj)
+{
+ stm_char *src = _RPyString_AsString(obj);
+ return STM_SEGMENT->segment_base + (uintptr_t)src;
+}
+
+static void _stm_expand_marker_for_pypy(uintptr_t odd_number,
+ object_t *following_object,
+ char *outputbuf, size_t outputbufsize)
+{
+ RPyString *co_filename =
+ *(RPyString **)(((char *)following_object) + g_co_filename_ofs);
+ RPyString *co_name =
+ *(RPyString **)(((char *)following_object) + g_co_name_ofs);
+ long co_firstlineno =
+ *(long *)(((char *)following_object) + g_co_firstlineno_ofs);
+ RPyString *co_lnotab =
+ *(RPyString **)(((char *)following_object) + g_co_lnotab_ofs);
+
+ char *ntrunc = "", *fntrunc = "";
+
+ long remaining = outputbufsize - 32;
+ long nlen = RPyString_Size(co_name);
+ char *name = _RPyString_AsString_Real(co_name);
+ if (nlen > remaining / 2) {
+ nlen = remaining / 2;
+ ntrunc = "...";
+ }
+ remaining -= nlen;
+
+ long fnlen = RPyString_Size(co_filename);
+ char *fn = _RPyString_AsString_Real(co_filename);
+ if (fnlen > remaining) {
+ fn += (fnlen - remaining);
+ fnlen = remaining;
+ fntrunc = "...";
+ }
+
+ long tablen = RPyString_Size(co_lnotab);
+ char *tab = _RPyString_AsString_Real(co_lnotab);
+ uintptr_t next_instr = odd_number >> 1;
+ long line = co_firstlineno;
+ uintptr_t i, addr = 0;
+ for (i = 0; i < tablen; i += 2) {
+ addr += ((unsigned char *)tab)[i];
+ if (addr > next_instr)
+ break;
+ line += ((unsigned char *)tab)[i + 1];
+ }
+
+ snprintf(outputbuf, outputbufsize, "File \"%s%.*s\", line %ld, in %.*s%s",
+ fntrunc, (int)fnlen, fn, line, (int)nlen, name, ntrunc);
+}
+
+void pypy_stm_setup_expand_marker(long co_filename_ofs,
+ long co_name_ofs,
+ long co_firstlineno_ofs,
+ long co_lnotab_ofs)
+{
+ g_co_filename_ofs = co_filename_ofs;
+ g_co_name_ofs = co_name_ofs;
+ g_co_firstlineno_ofs = co_firstlineno_ofs;
+ g_co_lnotab_ofs = co_lnotab_ofs;
+ stmcb_expand_marker = _stm_expand_marker_for_pypy;
+}
diff --git a/rpython/translator/stm/src_stm/stmgcintf.h
b/rpython/translator/stm/src_stm/stmgcintf.h
--- a/rpython/translator/stm/src_stm/stmgcintf.h
+++ b/rpython/translator/stm/src_stm/stmgcintf.h
@@ -26,6 +26,11 @@
void _pypy_stm_become_inevitable(const char *);
void pypy_stm_become_globally_unique_transaction(void);
+void pypy_stm_setup_expand_marker(long co_filename_ofs,
+ long co_name_ofs,
+ long co_firstlineno_ofs,
+ long co_lnotab_ofs);
+
static inline void pypy_stm_become_inevitable(const char *msg)
{
diff --git a/rpython/translator/stm/test/test_ztranslated.py
b/rpython/translator/stm/test/test_ztranslated.py
--- a/rpython/translator/stm/test/test_ztranslated.py
+++ b/rpython/translator/stm/test/test_ztranslated.py
@@ -240,6 +240,7 @@
assert 'ok\n' in data
def test_abort_info(self):
+ py.test.skip("goes away")
class Parent(object):
pass
class Foobar(Parent):
@@ -492,3 +493,60 @@
data = cbuilder.cmdexec('')
assert '-84\n' in data
assert '-1298\n' in data
+
+ def test_pypy_marker(self):
+ class PyCode(object):
+ def __init__(self, co_filename, co_name,
+ co_firstlineno, co_lnotab):
+ self.co_filename = co_filename
+ self.co_name = co_name
+ self.co_firstlineno = co_firstlineno
+ self.co_lnotab = co_lnotab
+
+ def run_interpreter(pycode):
+ print 'starting', pycode.co_name
+ rstm.push_marker(1, pycode)
+ for i in range(10):
+ p = llop.stm_expand_marker(rffi.CCHARP)
+ print rffi.charp2str(p)
+ rstm.update_marker_num(i * 2 + 1)
+ rstm.pop_marker()
+ print 'stopping', pycode.co_name
+
+ def main(argv):
+ pycode1 = PyCode("/tmp/foobar.py", "baz", 40, "\x00\x01\x05\x01")
+ pycode2 = PyCode("/tmp/foobaz.py", "bar", 70, "\x00\x01\x04\x02")
+ llop.stm_setup_expand_marker_for_pypy(
+ lltype.Void, pycode1,
+ "co_filename", "co_name", "co_firstlineno", "co_lnotab")
+
+ run_interpreter(pycode1)
+ run_interpreter(pycode2)
+ return 0
+
+ t, cbuilder = self.compile(main)
+ data = cbuilder.cmdexec('')
+ assert ('starting baz\n'
+ 'File "/tmp/foobar.py", line 41, in baz\n'
+ 'File "/tmp/foobar.py", line 41, in baz\n'
+ 'File "/tmp/foobar.py", line 41, in baz\n'
+ 'File "/tmp/foobar.py", line 41, in baz\n'
+ 'File "/tmp/foobar.py", line 41, in baz\n'
+ 'File "/tmp/foobar.py", line 42, in baz\n'
+ 'File "/tmp/foobar.py", line 42, in baz\n'
+ 'File "/tmp/foobar.py", line 42, in baz\n'
+ 'File "/tmp/foobar.py", line 42, in baz\n'
+ 'File "/tmp/foobar.py", line 42, in baz\n'
+ 'stopping baz\n') in data
+ assert ('starting bar\n'
+ 'File "/tmp/foobaz.py", line 71, in bar\n'
+ 'File "/tmp/foobaz.py", line 71, in bar\n'
+ 'File "/tmp/foobaz.py", line 71, in bar\n'
+ 'File "/tmp/foobaz.py", line 71, in bar\n'
+ 'File "/tmp/foobaz.py", line 73, in bar\n'
+ 'File "/tmp/foobaz.py", line 73, in bar\n'
+ 'File "/tmp/foobaz.py", line 73, in bar\n'
+ 'File "/tmp/foobaz.py", line 73, in bar\n'
+ 'File "/tmp/foobaz.py", line 73, in bar\n'
+ 'File "/tmp/foobaz.py", line 73, in bar\n'
+ 'stopping bar\n') in data
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit