[pypy-commit] pypy default: merged upstream
alex_gaynor
noreply at buildbot.pypy.org
Sat Jul 2 19:20:22 CEST 2011
Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch:
Changeset: r45283:bfe1dfefd9a1
Date: 2011-07-02 10:27 -0700
http://bitbucket.org/pypy/pypy/changeset/bfe1dfefd9a1/
Log: merged upstream
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
@@ -765,6 +765,7 @@
"""
short_preamble = None
failed_states = None
+ retraced_count = 0
terminating = False # see TerminatingLoopToken in compile.py
outermost_jitdriver_sd = None
# and more data specified by the backend when the loop is compiled
diff --git a/pypy/jit/metainterp/optimizeopt/unroll.py b/pypy/jit/metainterp/optimizeopt/unroll.py
--- a/pypy/jit/metainterp/optimizeopt/unroll.py
+++ b/pypy/jit/metainterp/optimizeopt/unroll.py
@@ -676,24 +676,28 @@
jumpop = self.optimizer.newoperations.pop()
assert jumpop.getopnum() == rop.JUMP
for guard in extra_guards:
- descr = sh.start_resumedescr.clone_if_mutable()
- self.inliner.inline_descr_inplace(descr)
- guard.setdescr(descr)
+ d = sh.start_resumedescr.clone_if_mutable()
+ self.inliner.inline_descr_inplace(d)
+ guard.setdescr(d)
self.emit_operation(guard)
self.optimizer.newoperations.append(jumpop)
return
- retraced_count = len(short)
- if descr.failed_states:
- retraced_count += len(descr.failed_states)
+ retraced_count = descr.retraced_count
+ descr.retraced_count += 1
limit = self.optimizer.metainterp_sd.warmrunnerdesc.memory_manager.retrace_limit
if not self.retraced and retraced_count<limit:
if not descr.failed_states:
+ debug_print("Retracing (%d of %d)" % (retraced_count,
+ limit))
raise RetraceLoop
for failed in descr.failed_states:
if failed.generalization_of(virtual_state):
# Retracing once more will most likely fail again
break
else:
+ debug_print("Retracing (%d of %d)" % (retraced_count,
+ limit))
+
raise RetraceLoop
else:
if not descr.failed_states:
diff --git a/pypy/jit/metainterp/test/test_ajit.py b/pypy/jit/metainterp/test/test_ajit.py
--- a/pypy/jit/metainterp/test/test_ajit.py
+++ b/pypy/jit/metainterp/test/test_ajit.py
@@ -1676,8 +1676,8 @@
return a1.val + b1.val
res = self.meta_interp(g, [6, 14])
assert res == g(6, 14)
- self.check_loop_count(9)
- self.check_loops(getarrayitem_gc=8, everywhere=True)
+ self.check_loop_count(8)
+ self.check_loops(getarrayitem_gc=7, everywhere=True)
py.test.skip("for the following, we need setarrayitem(varindex)")
self.check_loops(getarrayitem_gc=6, everywhere=True)
@@ -2314,6 +2314,66 @@
assert res == -2
#self.check_loops(getarrayitem_gc=0, setarrayitem_gc=0) -- xxx?
+ def test_retrace_ending_up_retrazing_another_loop(self):
+
+ myjitdriver = JitDriver(greens = ['pc'], reds = ['n', 'i', 'sa'])
+ bytecode = "0+sI0+SI"
+ def f(n):
+ myjitdriver.set_param('threshold', 3)
+ myjitdriver.set_param('trace_eagerness', 1)
+ myjitdriver.set_param('retrace_limit', 5)
+ pc = sa = i = 0
+ while pc < len(bytecode):
+ myjitdriver.jit_merge_point(pc=pc, n=n, sa=sa, i=i)
+ n = hint(n, promote=True)
+ op = bytecode[pc]
+ if op == '0':
+ i = 0
+ elif op == '+':
+ i += 1
+ elif op == 's':
+ sa += i
+ elif op == 'S':
+ sa += 2
+ elif op == 'I':
+ if i < n:
+ pc -= 2
+ myjitdriver.can_enter_jit(pc=pc, n=n, sa=sa, i=i)
+ continue
+ pc += 1
+ return sa
+
+ def g(n1, n2):
+ for i in range(10):
+ f(n1)
+ for i in range(10):
+ f(n2)
+
+ nn = [10, 3]
+ assert self.meta_interp(g, nn) == g(*nn)
+
+ # The attempts of retracing first loop will end up retracing the
+ # second and thus fail 5 times, saturating the retrace_count. Instead a
+ # bridge back to the preamble of the first loop is produced. A guard in
+ # this bridge is later traced resulting in a retrace of the second loop.
+ # Thus we end up with:
+ # 1 preamble and 1 specialized version of first loop
+ # 1 preamble and 2 specialized version of second loop
+ self.check_tree_loop_count(2 + 3)
+
+ # FIXME: Add a gloabl retrace counter and test that we are not trying more than 5 times.
+
+ def g(n):
+ for i in range(n):
+ for j in range(10):
+ f(n-i)
+
+ res = self.meta_interp(g, [10])
+ assert res == g(10)
+ # 1 preamble and 6 speciealized versions of each loop
+ self.check_tree_loop_count(2*(1 + 6))
+
+
class TestOOtype(BasicTests, OOJitMixin):
def test_oohash(self):
diff --git a/pypy/module/pyexpat/__init__.py b/pypy/module/pyexpat/__init__.py
--- a/pypy/module/pyexpat/__init__.py
+++ b/pypy/module/pyexpat/__init__.py
@@ -2,6 +2,22 @@
from pypy.interpreter.mixedmodule import MixedModule
+class ErrorsModule(MixedModule):
+ "Definition of pyexpat.errors module."
+
+ appleveldefs = {
+ }
+
+ interpleveldefs = {
+ }
+
+ def setup_after_space_initialization(self):
+ from pypy.module.pyexpat import interp_pyexpat
+ for name in interp_pyexpat.xml_error_list:
+ self.space.setattr(self, self.space.wrap(name),
+ interp_pyexpat.ErrorString(self.space,
+ getattr(interp_pyexpat, name)))
+
class Module(MixedModule):
"Python wrapper for Expat parser."
@@ -21,6 +37,10 @@
'version_info': 'interp_pyexpat.get_expat_version_info(space)',
}
+ submodules = {
+ 'errors': ErrorsModule,
+ }
+
for name in ['XML_PARAM_ENTITY_PARSING_NEVER',
'XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE',
'XML_PARAM_ENTITY_PARSING_ALWAYS']:
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
@@ -31,6 +31,48 @@
XML_Content_Ptr = lltype.Ptr(lltype.ForwardReference())
XML_Parser = rffi.COpaquePtr(typedef='XML_Parser')
+xml_error_list = [
+ "XML_ERROR_NO_MEMORY",
+ "XML_ERROR_SYNTAX",
+ "XML_ERROR_NO_ELEMENTS",
+ "XML_ERROR_INVALID_TOKEN",
+ "XML_ERROR_UNCLOSED_TOKEN",
+ "XML_ERROR_PARTIAL_CHAR",
+ "XML_ERROR_TAG_MISMATCH",
+ "XML_ERROR_DUPLICATE_ATTRIBUTE",
+ "XML_ERROR_JUNK_AFTER_DOC_ELEMENT",
+ "XML_ERROR_PARAM_ENTITY_REF",
+ "XML_ERROR_UNDEFINED_ENTITY",
+ "XML_ERROR_RECURSIVE_ENTITY_REF",
+ "XML_ERROR_ASYNC_ENTITY",
+ "XML_ERROR_BAD_CHAR_REF",
+ "XML_ERROR_BINARY_ENTITY_REF",
+ "XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF",
+ "XML_ERROR_MISPLACED_XML_PI",
+ "XML_ERROR_UNKNOWN_ENCODING",
+ "XML_ERROR_INCORRECT_ENCODING",
+ "XML_ERROR_UNCLOSED_CDATA_SECTION",
+ "XML_ERROR_EXTERNAL_ENTITY_HANDLING",
+ "XML_ERROR_NOT_STANDALONE",
+ "XML_ERROR_UNEXPECTED_STATE",
+ "XML_ERROR_ENTITY_DECLARED_IN_PE",
+ "XML_ERROR_FEATURE_REQUIRES_XML_DTD",
+ "XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING",
+ # Added in Expat 1.95.7.
+ "XML_ERROR_UNBOUND_PREFIX",
+ # Added in Expat 1.95.8.
+ "XML_ERROR_UNDECLARING_PREFIX",
+ "XML_ERROR_INCOMPLETE_PE",
+ "XML_ERROR_XML_DECL",
+ "XML_ERROR_TEXT_DECL",
+ "XML_ERROR_PUBLICID",
+ "XML_ERROR_SUSPENDED",
+ "XML_ERROR_NOT_SUSPENDED",
+ "XML_ERROR_ABORTED",
+ "XML_ERROR_FINISHED",
+ "XML_ERROR_SUSPEND_PE",
+ ]
+
class CConfigure:
_compilation_info_ = eci
XML_Content = rffi_platform.Struct('XML_Content', [
@@ -56,6 +98,9 @@
XML_FALSE = rffi_platform.ConstantInteger('XML_FALSE')
XML_TRUE = rffi_platform.ConstantInteger('XML_TRUE')
+ for name in xml_error_list:
+ locals()[name] = rffi_platform.ConstantInteger(name)
+
for k, v in rffi_platform.configure(CConfigure).items():
globals()[k] = v
@@ -298,7 +343,8 @@
XML_GetErrorCode = expat_external(
'XML_GetErrorCode', [XML_Parser], rffi.INT)
XML_ErrorString = expat_external(
- 'XML_ErrorString', [rffi.INT], rffi.CCHARP)
+ 'XML_ErrorString', [rffi.INT],
+ rffi.CCHARP)
XML_GetCurrentLineNumber = expat_external(
'XML_GetCurrentLineNumber', [XML_Parser], rffi.INT)
XML_GetErrorLineNumber = XML_GetCurrentLineNumber
diff --git a/pypy/module/pyexpat/test/test_parser.py b/pypy/module/pyexpat/test/test_parser.py
--- a/pypy/module/pyexpat/test/test_parser.py
+++ b/pypy/module/pyexpat/test/test_parser.py
@@ -38,7 +38,7 @@
parser = pyexpat.ParserCreate()
raises(pyexpat.ExpatError, "parser.Parse(xml, True)")
- def test_encoding(self):
+ def test_encoding_argument(self):
import pyexpat
for encoding_arg in (None, 'utf-8', 'iso-8859-1'):
for namespace_arg in (None, '{'):
@@ -68,7 +68,7 @@
assert p.buffer_size == 150
raises(TypeError, setattr, p, 'buffer_size', sys.maxint + 1)
- def test_encoding(self):
+ def test_encoding_xml(self):
# use one of the few encodings built-in in expat
xml = "<?xml version='1.0' encoding='iso-8859-1'?><s>caf\xe9</s>"
import pyexpat
@@ -120,3 +120,14 @@
return True
p.ExternalEntityRefHandler = handler
p.Parse(xml)
+
+ def test_errors(self):
+ import types
+ import pyexpat
+ assert isinstance(pyexpat.errors, types.ModuleType)
+ # check a few random errors
+ assert pyexpat.errors.XML_ERROR_SYNTAX == 'syntax error'
+ assert (pyexpat.errors.XML_ERROR_INCORRECT_ENCODING ==
+ 'encoding specified in XML declaration is incorrect')
+ assert (pyexpat.errors.XML_ERROR_XML_DECL ==
+ 'XML declaration not well-formed')
More information about the pypy-commit
mailing list