[pypy-commit] pypy concurrent-marksweep: Hack hack hack until the translator is sure that the collector thread
arigo
noreply at buildbot.pypy.org
Sat Oct 8 14:40:19 CEST 2011
Author: Armin Rigo <arigo at tunes.org>
Branch: concurrent-marksweep
Changeset: r47876:49ab73172117
Date: 2011-10-08 14:39 +0200
http://bitbucket.org/pypy/pypy/changeset/49ab73172117/
Log: Hack hack hack until the translator is sure that the collector
thread doesn't do anything with exceptions. This lets us keep the
global exception state non-thread-local.
diff --git a/pypy/module/thread/ll_thread.py b/pypy/module/thread/ll_thread.py
--- a/pypy/module/thread/ll_thread.py
+++ b/pypy/module/thread/ll_thread.py
@@ -39,6 +39,9 @@
return rffi.cast(rffi.LONG, ident)
CALLBACK = lltype.Ptr(lltype.FuncType([], lltype.Void))
+c_thread_start_nowrapper = llexternal('RPyThreadStart', [CALLBACK], rffi.LONG,
+ _callable=_emulated_start_new_thread,
+ _nowrapper=True)
c_thread_start = llexternal('RPyThreadStart', [CALLBACK], rffi.LONG,
_callable=_emulated_start_new_thread,
threadsafe=True) # release the GIL, but most
diff --git a/pypy/rlib/debug.py b/pypy/rlib/debug.py
--- a/pypy/rlib/debug.py
+++ b/pypy/rlib/debug.py
@@ -210,7 +210,7 @@
c_pythonfunction = hop.inputconst(lltype.Void, pythonfunction)
args_v = [hop.inputarg(hop.args_r[i], arg=i)
for i in range(2, hop.nb_args)]
- hop.exception_is_here()
+ hop.exception_cannot_occur()
return hop.genop('debug_llinterpcall', [c_pythonfunction] + args_v,
resulttype=RESTYPE)
diff --git a/pypy/rpython/lltypesystem/lloperation.py b/pypy/rpython/lltypesystem/lloperation.py
--- a/pypy/rpython/lltypesystem/lloperation.py
+++ b/pypy/rpython/lltypesystem/lloperation.py
@@ -530,8 +530,7 @@
'debug_flush': LLOp(canrun=True),
'debug_assert': LLOp(tryfold=True),
'debug_fatalerror': LLOp(),
- 'debug_llinterpcall': LLOp(canraise=(Exception,)),
- # Python func call 'res=arg[0](*arg[1:])'
+ 'debug_llinterpcall': LLOp(), # Python func call 'res=arg[0](*arg[1:])'
# in backends, abort() or whatever is fine
'debug_start_traceback': LLOp(),
'debug_record_traceback': LLOp(),
diff --git a/pypy/rpython/memory/gc/base.py b/pypy/rpython/memory/gc/base.py
--- a/pypy/rpython/memory/gc/base.py
+++ b/pypy/rpython/memory/gc/base.py
@@ -231,7 +231,7 @@
j += 1
item += itemlength
length -= 1
- if self.has_custom_trace(typeid):
+ if self.has_custom_trace(typeid) and 0: # XXX XXX temporarily disabled
generator = self.get_custom_trace(typeid)
item = llmemory.NULL
while True:
diff --git a/pypy/rpython/memory/gc/concurrentms.py b/pypy/rpython/memory/gc/concurrentms.py
--- a/pypy/rpython/memory/gc/concurrentms.py
+++ b/pypy/rpython/memory/gc/concurrentms.py
@@ -1,6 +1,7 @@
import time, sys
from pypy.rpython.lltypesystem import lltype, llmemory, llarena, llgroup, rffi
from pypy.rpython.lltypesystem.llmemory import raw_malloc_usage
+from pypy.rpython.annlowlevel import llhelper
from pypy.translator.tool.cbuild import ExternalCompilationInfo
from pypy.rlib.objectmodel import we_are_translated, running_on_llinterp
from pypy.rlib.debug import ll_assert
@@ -127,6 +128,7 @@
print 'Crash!', e.__class__.__name__, e
self._exc_info = sys.exc_info()
#
+ collector_start._should_never_raise_ = True
self.collector_start = collector_start
#
#self.mutex_lock = ...built in setup()
@@ -150,8 +152,9 @@
self.acquire(self.finished_lock)
self.acquire(self.ready_to_start_lock)
#
- self.collector_ident = ll_thread.start_new_thread(
- self.collector_start, ())
+ self.collector_ident = ll_thread.c_thread_start_nowrapper(
+ llhelper(ll_thread.CALLBACK, self.collector_start))
+ assert self.collector_ident != -1
def _teardown(self):
"Stop the collector thread after tests have run."
@@ -542,7 +545,12 @@
def collector_run(self):
"""Main function of the collector's thread."""
- while True:
+ #
+ # hack: make it an infinite loop, but in a way that the annotator
+ # doesn't notice. It prevents the caller from ending automatically
+ # in a "raise AssertionError", annoyingly, because we don't want
+ # any exception in this thread
+ while self.collection_running < 99:
#
# Wait for the lock to be released
self.acquire(self.ready_to_start_lock)
@@ -601,7 +609,7 @@
# acquired the 'mutex_lock', so all reachable objects have
# been marked.
if not self.gray_objects.non_empty():
- return
+ break
def _collect_mark(self):
current_mark = self.current_mark
diff --git a/pypy/rpython/memory/support.py b/pypy/rpython/memory/support.py
--- a/pypy/rpython/memory/support.py
+++ b/pypy/rpython/memory/support.py
@@ -1,7 +1,7 @@
-from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.rpython.lltypesystem import lltype, llmemory, llarena
from pypy.rlib.objectmodel import free_non_gc_object, we_are_translated
from pypy.rlib.rarithmetic import r_uint, LONG_BIT
-from pypy.rlib.debug import ll_assert
+from pypy.rlib.debug import ll_assert, fatalerror
from pypy.tool.identity_dict import identity_dict
@@ -39,10 +39,17 @@
if not self.free_list:
# we zero-initialize the chunks to make the translation
# backends happy, but we don't need to do it at run-time.
- zero = not we_are_translated()
- return lltype.malloc(CHUNK, flavor="raw", zero=zero,
- track_allocation=False)
-
+ if we_are_translated():
+ zero = 0
+ else:
+ zero = 2
+ size = llmemory.raw_malloc_usage(llmemory.sizeof(CHUNK))
+ addr = llarena.arena_malloc(size, zero)
+ if not addr:
+ fatalerror("out of memory in GC support code")
+ llarena.arena_reserve(addr, llmemory.sizeof(CHUNK))
+ return llmemory.cast_adr_to_ptr(addr, lltype.Ptr(CHUNK))
+
result = self.free_list
self.free_list = result.next
return result
diff --git a/pypy/translator/backendopt/canraise.py b/pypy/translator/backendopt/canraise.py
--- a/pypy/translator/backendopt/canraise.py
+++ b/pypy/translator/backendopt/canraise.py
@@ -12,20 +12,31 @@
class RaiseAnalyzer(graphanalyze.BoolGraphAnalyzer):
def analyze_simple_operation(self, op, graphinfo):
try:
- return bool(LL_OPERATIONS[op.opname].canraise)
+ if LL_OPERATIONS[op.opname].canraise:
+ self.reason = op
+ return True
+ return False
except KeyError:
log.WARNING("Unknown operation: %s" % op.opname)
+ self.reason = op
return True
def analyze_external_call(self, op, seen=None):
fnobj = get_funcobj(op.args[0].value)
- return getattr(fnobj, 'canraise', True)
+ if getattr(fnobj, 'canraise', True):
+ self.reason = 'external call:', fnobj
+ return True
+ return False
def analyze_external_method(self, op, TYPE, meth):
assert op.opname == 'oosend'
- return getattr(meth, '_can_raise', True)
+ if getattr(meth, '_can_raise', True):
+ self.reason = 'external method:', meth
+ return True
+ return False
def analyze_exceptblock(self, block, seen=None):
+ self.reason = "except block:", block
return True
# backward compatible interface
diff --git a/pypy/translator/backendopt/graphanalyze.py b/pypy/translator/backendopt/graphanalyze.py
--- a/pypy/translator/backendopt/graphanalyze.py
+++ b/pypy/translator/backendopt/graphanalyze.py
@@ -4,6 +4,7 @@
class GraphAnalyzer(object):
verbose = False
+ reason = None
def __init__(self, translator):
self.translator = translator
@@ -86,6 +87,7 @@
if graphs is None:
if self.verbose:
print '\t%s to unknown' % (op,)
+ self.reason = op
return self.top_result()
x = self.analyze_indirect_call(graphs, seen)
if self.verbose and x:
diff --git a/pypy/translator/exceptiontransform.py b/pypy/translator/exceptiontransform.py
--- a/pypy/translator/exceptiontransform.py
+++ b/pypy/translator/exceptiontransform.py
@@ -198,8 +198,19 @@
assert self.same_obj(self.exc_data_ptr, graph.exceptiontransformed)
return
else:
- self.raise_analyzer.analyze_direct_call(graph)
+ # side-effect: perform the analysis of all graphs reachable from
+ # 'graph'
+ can_raise = self.raise_analyzer.analyze_direct_call(graph)
graph.exceptiontransformed = self.exc_data_ptr
+ func = getattr(graph, 'func', None)
+ if getattr(func, '_should_never_raise_', False):
+ if not can_raise:
+ return
+ ra = canraise.RaiseAnalyzer(self.translator)
+ ra.analyze_direct_call(graph)
+ raise Exception("%r is marked as _should_never_raise_, "
+ "but is found to raise. Reason: %r" % (
+ graph, ra.reason))
join_blocks(graph)
# collect the blocks before changing them
More information about the pypy-commit
mailing list