[pypy-svn] r79045 - in pypy/branch/fast-forward: lib_pypy/ctypes_config_cache lib_pypy/ctypes_config_cache/test pypy/doc pypy/jit/backend/llsupport pypy/jit/backend/llsupport/test pypy/jit/backend/test pypy/jit/backend/x86 pypy/jit/backend/x86/test pypy/jit/codewriter pypy/jit/codewriter/test pypy/jit/metainterp pypy/jit/metainterp/optimizeopt pypy/jit/metainterp/test pypy/jit/tool pypy/module/_stackless/test pypy/module/cpyext pypy/module/posix pypy/objspace/flow pypy/objspace/flow/test pypy/rlib pypy/rlib/test pypy/rpython pypy/rpython/memory/gc pypy/rpython/memory/gctransform pypy/rpython/test pypy/translator/c pypy/translator/c/test pypy/translator/cli/src pypy/translator/goal pypy/translator/goal/test2

afa at codespeak.net afa at codespeak.net
Fri Nov 12 16:29:28 CET 2010


Author: afa
Date: Fri Nov 12 16:29:24 2010
New Revision: 79045

Added:
   pypy/branch/fast-forward/pypy/doc/release-1.4.0.txt
      - copied unchanged from r79038, pypy/trunk/pypy/doc/release-1.4.0.txt
   pypy/branch/fast-forward/pypy/module/_stackless/test/conftest.py
      - copied unchanged from r79038, pypy/trunk/pypy/module/_stackless/test/conftest.py
Modified:
   pypy/branch/fast-forward/lib_pypy/ctypes_config_cache/dumpcache.py
   pypy/branch/fast-forward/lib_pypy/ctypes_config_cache/test/test_cache.py
   pypy/branch/fast-forward/pypy/jit/backend/llsupport/descr.py
   pypy/branch/fast-forward/pypy/jit/backend/llsupport/gc.py
   pypy/branch/fast-forward/pypy/jit/backend/llsupport/test/test_descr.py
   pypy/branch/fast-forward/pypy/jit/backend/test/runner_test.py
   pypy/branch/fast-forward/pypy/jit/backend/x86/assembler.py
   pypy/branch/fast-forward/pypy/jit/backend/x86/test/test_zrpy_gc.py
   pypy/branch/fast-forward/pypy/jit/backend/x86/test/test_ztranslation.py
   pypy/branch/fast-forward/pypy/jit/codewriter/assembler.py
   pypy/branch/fast-forward/pypy/jit/codewriter/call.py
   pypy/branch/fast-forward/pypy/jit/codewriter/codewriter.py
   pypy/branch/fast-forward/pypy/jit/codewriter/effectinfo.py
   pypy/branch/fast-forward/pypy/jit/codewriter/jtransform.py
   pypy/branch/fast-forward/pypy/jit/codewriter/test/test_jtransform.py
   pypy/branch/fast-forward/pypy/jit/metainterp/optimizeopt/optimizer.py
   pypy/branch/fast-forward/pypy/jit/metainterp/optimizeopt/string.py
   pypy/branch/fast-forward/pypy/jit/metainterp/pyjitpl.py
   pypy/branch/fast-forward/pypy/jit/metainterp/resume.py
   pypy/branch/fast-forward/pypy/jit/metainterp/test/test_del.py
   pypy/branch/fast-forward/pypy/jit/metainterp/test/test_optimizeopt.py
   pypy/branch/fast-forward/pypy/jit/metainterp/test/test_resume.py
   pypy/branch/fast-forward/pypy/jit/metainterp/test/test_virtualref.py
   pypy/branch/fast-forward/pypy/jit/tool/pypytrace-mode.el
   pypy/branch/fast-forward/pypy/module/cpyext/api.py
   pypy/branch/fast-forward/pypy/module/cpyext/pyobject.py
   pypy/branch/fast-forward/pypy/module/posix/interp_posix.py
   pypy/branch/fast-forward/pypy/objspace/flow/objspace.py
   pypy/branch/fast-forward/pypy/objspace/flow/test/test_objspace.py
   pypy/branch/fast-forward/pypy/rlib/rarithmetic.py
   pypy/branch/fast-forward/pypy/rlib/streamio.py
   pypy/branch/fast-forward/pypy/rlib/test/test_rarithmetic.py
   pypy/branch/fast-forward/pypy/rpython/memory/gc/base.py
   pypy/branch/fast-forward/pypy/rpython/memory/gc/generation.py
   pypy/branch/fast-forward/pypy/rpython/memory/gc/inspector.py
   pypy/branch/fast-forward/pypy/rpython/memory/gc/minimark.py
   pypy/branch/fast-forward/pypy/rpython/memory/gc/semispace.py
   pypy/branch/fast-forward/pypy/rpython/memory/gctransform/framework.py
   pypy/branch/fast-forward/pypy/rpython/rmodel.py
   pypy/branch/fast-forward/pypy/rpython/test/test_rpbc.py
   pypy/branch/fast-forward/pypy/translator/c/genc.py
   pypy/branch/fast-forward/pypy/translator/c/test/test_newgc.py
   pypy/branch/fast-forward/pypy/translator/cli/src/pypylib.cs
   pypy/branch/fast-forward/pypy/translator/goal/app_main.py
   pypy/branch/fast-forward/pypy/translator/goal/test2/test_app_main.py
Log:
Merge from trunk
svn merge -r78901:79038 ../trunk


Modified: pypy/branch/fast-forward/lib_pypy/ctypes_config_cache/dumpcache.py
==============================================================================
--- pypy/branch/fast-forward/lib_pypy/ctypes_config_cache/dumpcache.py	(original)
+++ pypy/branch/fast-forward/lib_pypy/ctypes_config_cache/dumpcache.py	Fri Nov 12 16:29:24 2010
@@ -16,8 +16,10 @@
 except ImportError:
     from pypy.jit.backend import detect_cpu
     cpumodel = detect_cpu.autodetect_main_model_and_size()
-mod = __import__("ctypes_config_cache._%s_%%s_" %% (cpumodel,),
-                 None, None, ["*"])
+# XXX relative import, should be removed together with
+# XXX the relative imports done e.g. by lib_pypy/pypy_test/test_hashlib
+mod = __import__("_%s_%%s_" %% (cpumodel,),
+                 globals(), locals(), ["*"])
 globals().update(mod.__dict__)\
 ''' % (basename,)
     g.close()

Modified: pypy/branch/fast-forward/lib_pypy/ctypes_config_cache/test/test_cache.py
==============================================================================
--- pypy/branch/fast-forward/lib_pypy/ctypes_config_cache/test/test_cache.py	(original)
+++ pypy/branch/fast-forward/lib_pypy/ctypes_config_cache/test/test_cache.py	Fri Nov 12 16:29:24 2010
@@ -7,9 +7,8 @@
 
 def run(filename, outputname):
     filepath = dirpath.join(filename)
-    tmpdir2 = udir.ensure('testcache-' + filename, dir=True)
-    tmpdir = tmpdir2.ensure('ctypes_config_cache', dir=True)
-    tmpdir.join('__init__.py').write('\n')
+    tmpdir = udir.ensure('testcache-' + os.path.splitext(filename)[0],
+                         dir=True)
     tmpdir.join('dumpcache.py').write(dirpath.join('dumpcache.py').read())
     path = sys.path[:]
     try:
@@ -21,13 +20,13 @@
     #
     outputpath = tmpdir.join(outputname)
     assert outputpath.check(exists=1)
-    d = {}
+    modname = os.path.splitext(outputname)[0]
     try:
-        sys.path.insert(0, str(tmpdir2))
+        sys.path.insert(0, str(tmpdir))
+        d = {}
         execfile(str(outputpath), d)
     finally:
         sys.path[:] = path
-        sys.modules.pop('ctypes_config_cache', None)
     return d
 
 

Modified: pypy/branch/fast-forward/pypy/jit/backend/llsupport/descr.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/backend/llsupport/descr.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/backend/llsupport/descr.py	Fri Nov 12 16:29:24 2010
@@ -130,6 +130,7 @@
 # ArrayDescrs
 
 _A = lltype.GcArray(lltype.Signed)     # a random gcarray
+_AF = lltype.GcArray(lltype.Float)     # an array of C doubles
 
 
 class BaseArrayDescr(AbstractDescr):
@@ -171,16 +172,21 @@
     _clsname = 'GcPtrArrayDescr'
     _is_array_of_pointers = True
 
-_CA = rffi.CArray(lltype.Signed)
+class FloatArrayDescr(BaseArrayDescr):
+    _clsname = 'FloatArrayDescr'
+    _is_array_of_floats = True
+    def get_base_size(self, translate_support_code):
+        basesize, _, _ = symbolic.get_array_token(_AF, translate_support_code)
+        return basesize
+    def get_item_size(self, translate_support_code):
+        return symbolic.get_size(lltype.Float, translate_support_code)
 
 class BaseArrayNoLengthDescr(BaseArrayDescr):
     def get_base_size(self, translate_support_code):
-        basesize, _, _ = symbolic.get_array_token(_CA, translate_support_code)
-        return basesize
+        return 0
 
     def get_ofs_length(self, translate_support_code):
-        _, _, ofslength = symbolic.get_array_token(_CA, translate_support_code)
-        return ofslength
+        return -1
 
 class NonGcPtrArrayNoLengthDescr(BaseArrayNoLengthDescr):
     _clsname = 'NonGcPtrArrayNoLengthDescr'
@@ -192,6 +198,8 @@
     _is_array_of_pointers = True
 
 def getArrayDescrClass(ARRAY):
+    if ARRAY.OF is lltype.Float:
+        return FloatArrayDescr
     return getDescrClass(ARRAY.OF, BaseArrayDescr, GcPtrArrayDescr,
                          NonGcPtrArrayDescr, 'Array', 'get_item_size',
                          '_is_array_of_floats', '_is_item_signed')
@@ -219,7 +227,8 @@
         basesize, itemsize, ofslength = symbolic.get_array_token(ARRAY, False)
         assert basesize == arraydescr.get_base_size(False)
         assert itemsize == arraydescr.get_item_size(False)
-        assert ofslength == arraydescr.get_ofs_length(False)
+        if not ARRAY._hints.get('nolength', False):
+            assert ofslength == arraydescr.get_ofs_length(False)
         if isinstance(ARRAY, lltype.GcArray):
             gccache.init_array_descr(ARRAY, arraydescr)
         cache[ARRAY] = arraydescr

Modified: pypy/branch/fast-forward/pypy/jit/backend/llsupport/gc.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/backend/llsupport/gc.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/backend/llsupport/gc.py	Fri Nov 12 16:29:24 2010
@@ -19,6 +19,7 @@
 # ____________________________________________________________
 
 class GcLLDescription(GcCache):
+    minimal_size_in_nursery = 0
     def __init__(self, gcdescr, translator=None, rtyper=None):
         GcCache.__init__(self, translator is not None, rtyper)
         self.gcdescr = gcdescr
@@ -386,6 +387,7 @@
         (self.array_basesize, _, self.array_length_ofs) = \
              symbolic.get_array_token(lltype.GcArray(lltype.Signed), True)
         self.max_size_of_young_obj = self.GCClass.JIT_max_size_of_young_obj()
+        self.minimal_size_in_nursery=self.GCClass.JIT_minimal_size_in_nursery()
 
         # make a malloc function, with three arguments
         def malloc_basic(size, tid):
@@ -468,6 +470,7 @@
         def malloc_fixedsize_slowpath(size):
             if self.DEBUG:
                 random_usage_of_xmm_registers()
+            assert size >= self.minimal_size_in_nursery
             try:
                 gcref = llop1.do_malloc_fixedsize_clear(llmemory.GCREF,
                                             0, size, True, False, False)

Modified: pypy/branch/fast-forward/pypy/jit/backend/llsupport/test/test_descr.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/backend/llsupport/test/test_descr.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/backend/llsupport/test/test_descr.py	Fri Nov 12 16:29:24 2010
@@ -5,6 +5,7 @@
 from pypy.rpython.annlowlevel import llhelper
 from pypy.jit.metainterp.history import BoxInt, BoxFloat, BoxPtr
 from pypy.jit.metainterp import history
+import struct
 
 def test_get_size_descr():
     c0 = GcCache(False)
@@ -130,11 +131,13 @@
     assert not descr3.is_array_of_floats()
     assert     descr4.is_array_of_floats()
     #
-    WORD = rffi.sizeof(lltype.Signed)
-    assert descr1.get_base_size(False) == WORD
-    assert descr2.get_base_size(False) == WORD
-    assert descr3.get_base_size(False) == WORD
-    assert descr4.get_base_size(False) == WORD
+    def get_alignment(code):
+        # Retrieve default alignment for the compiler/platform
+        return struct.calcsize('l' + code) - struct.calcsize(code)
+    assert descr1.get_base_size(False) == get_alignment('c')
+    assert descr2.get_base_size(False) == get_alignment('p')
+    assert descr3.get_base_size(False) == get_alignment('p')
+    assert descr4.get_base_size(False) == get_alignment('d')
     assert descr1.get_ofs_length(False) == 0
     assert descr2.get_ofs_length(False) == 0
     assert descr3.get_ofs_length(False) == 0

Modified: pypy/branch/fast-forward/pypy/jit/backend/test/runner_test.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/backend/test/runner_test.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/backend/test/runner_test.py	Fri Nov 12 16:29:24 2010
@@ -2168,12 +2168,14 @@
             # Tested with a function that intentionally does not cast the
             # result to RESTYPE, but makes sure that we return the whole
             # value in eax or rax.
-            eci = ExternalCompilationInfo(separate_module_sources=["""
+            eci = ExternalCompilationInfo(
+                separate_module_sources=["""
                 long fn_test_result_of_call(long x)
                 {
                     return x + 1;
                 }
-            """])
+                """],
+                export_symbols=['fn_test_result_of_call'])
             f = rffi.llexternal('fn_test_result_of_call', [lltype.Signed],
                                 RESTYPE, compilation_info=eci, _nowrapper=True)
             value = intmask(0xFFEEDDCCBBAA9988)
@@ -2199,12 +2201,14 @@
             # Tested with a function that intentionally does not cast the
             # result to RESTYPE, but makes sure that we return the whole
             # value in eax or rax.
-            eci = ExternalCompilationInfo(separate_module_sources=["""
+            eci = ExternalCompilationInfo(
+                separate_module_sources=["""
                 long fn_test_result_of_call(long x)
                 {
                     return x + 1;
                 }
-            """])
+                """],
+                export_symbols=['fn_test_result_of_call'])
             f = rffi.llexternal('fn_test_result_of_call', [lltype.Signed],
                                 RESTYPE, compilation_info=eci, _nowrapper=True)
             value = intmask(0xFFEEDDCCBBAA9988)

Modified: pypy/branch/fast-forward/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/backend/x86/assembler.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/backend/x86/assembler.py	Fri Nov 12 16:29:24 2010
@@ -1853,6 +1853,7 @@
 
     def malloc_cond_fixedsize(self, nursery_free_adr, nursery_top_adr,
                               size, tid):
+        size = max(size, self.cpu.gc_ll_descr.minimal_size_in_nursery)
         self.mc.ensure_bytes_available(256)
         self.mc.MOV(eax, heap(nursery_free_adr))
         self.mc.LEA_rm(edx.value, (eax.value, size))

Modified: pypy/branch/fast-forward/pypy/jit/backend/x86/test/test_zrpy_gc.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/backend/x86/test/test_zrpy_gc.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/backend/x86/test/test_zrpy_gc.py	Fri Nov 12 16:29:24 2010
@@ -550,3 +550,29 @@
 
     def test_compile_framework_float(self):
         self.run('compile_framework_float')
+
+    def define_compile_framework_minimal_size_in_nursery(self):
+        S = lltype.GcStruct('S')    # no fields!
+        T = lltype.GcStruct('T', ('i', lltype.Signed))
+        @unroll_safe
+        def f42(n, x, x0, x1, x2, x3, x4, x5, x6, x7, l, s):
+            lst1 = []
+            lst2 = []
+            i = 0
+            while i < 42:
+                s1 = lltype.malloc(S)
+                t1 = lltype.malloc(T)
+                t1.i = 10000 + i + n
+                lst1.append(s1)
+                lst2.append(t1)
+                i += 1
+            i = 0
+            while i < 42:
+                check(lst2[i].i == 10000 + i + n)
+                i += 1
+            n -= 1
+            return n, x, x0, x1, x2, x3, x4, x5, x6, x7, l, s
+        return None, f42, None
+
+    def test_compile_framework_minimal_size_in_nursery(self):
+        self.run('compile_framework_minimal_size_in_nursery')

Modified: pypy/branch/fast-forward/pypy/jit/backend/x86/test/test_ztranslation.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/backend/x86/test/test_ztranslation.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/backend/x86/test/test_ztranslation.py	Fri Nov 12 16:29:24 2010
@@ -2,6 +2,7 @@
 from pypy.tool.udir import udir
 from pypy.rlib.jit import JitDriver, OPTIMIZER_FULL, unroll_parameters
 from pypy.rlib.jit import PARAMETERS, dont_look_inside
+from pypy.rlib.jit import hint
 from pypy.jit.metainterp.jitprof import Profiler
 from pypy.jit.backend.detect_cpu import getcpuclass
 from pypy.jit.backend.test.support import CCompiledMixin
@@ -9,6 +10,7 @@
 from pypy.translator.translator import TranslationContext
 from pypy.jit.backend.x86.arch import IS_X86_32, IS_X86_64
 from pypy.config.translationoption import DEFL_GC
+from pypy.rlib import rgc
 
 class TestTranslationX86(CCompiledMixin):
     CPUClass = getcpuclass()
@@ -82,12 +84,12 @@
                 argchain.arg(x)
                 res = func.call(argchain, rffi.DOUBLE)
                 i -= 1
-            return res
+            return int(res)
         #
         def main(i, j):
             return f(i, j) + libffi_stuff(i, j)
-        expected = f(40, -49)
-        res = self.meta_interp(f, [40, -49])
+        expected = main(40, -49)
+        res = self.meta_interp(main, [40, -49])
         assert res == expected
 
     def test_direct_assembler_call_translates(self):

Modified: pypy/branch/fast-forward/pypy/jit/codewriter/assembler.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/codewriter/assembler.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/codewriter/assembler.py	Fri Nov 12 16:29:24 2010
@@ -233,10 +233,9 @@
             addr = llmemory.cast_ptr_to_adr(value)
             self.list_of_addr2name.append((addr, name))
 
-    def finished(self):
+    def finished(self, callinfocollection):
         # Helper called at the end of assembling.  Registers the extra
         # functions shown in _callinfo_for_oopspec.
-        from pypy.jit.codewriter.effectinfo import _callinfo_for_oopspec
-        for _, func in _callinfo_for_oopspec.values():
+        for func in callinfocollection.all_function_addresses_as_int():
             func = heaptracker.int2adr(func)
             self.see_raw_object(func.ptr)

Modified: pypy/branch/fast-forward/pypy/jit/codewriter/call.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/codewriter/call.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/codewriter/call.py	Fri Nov 12 16:29:24 2010
@@ -7,7 +7,7 @@
 from pypy.jit.codewriter.jitcode import JitCode
 from pypy.jit.codewriter.effectinfo import VirtualizableAnalyzer
 from pypy.jit.codewriter.effectinfo import effectinfo_from_writeanalyze
-from pypy.jit.codewriter.effectinfo import EffectInfo
+from pypy.jit.codewriter.effectinfo import EffectInfo, CallInfoCollection
 from pypy.translator.simplify import get_funcobj, get_functype
 from pypy.rpython.lltypesystem import lltype, llmemory
 from pypy.translator.backendopt.canraise import RaiseAnalyzer
@@ -23,6 +23,7 @@
         self.jitdrivers_sd = jitdrivers_sd
         self.jitcodes = {}             # map {graph: jitcode}
         self.unfinished_graphs = []    # list of graphs with pending jitcodes
+        self.callinfocollection = CallInfoCollection()
         if hasattr(cpu, 'rtyper'):     # for tests
             self.rtyper = cpu.rtyper
             translator = self.rtyper.annotator.translator

Modified: pypy/branch/fast-forward/pypy/jit/codewriter/codewriter.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/codewriter/codewriter.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/codewriter/codewriter.py	Fri Nov 12 16:29:24 2010
@@ -73,7 +73,7 @@
             count += 1
             if not count % 500:
                 log.info("Produced %d jitcodes" % count)
-        self.assembler.finished()
+        self.assembler.finished(self.callcontrol.callinfocollection)
         heaptracker.finish_registering(self.cpu)
         log.info("there are %d JitCode instances." % count)
 

Modified: pypy/branch/fast-forward/pypy/jit/codewriter/effectinfo.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/codewriter/effectinfo.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/codewriter/effectinfo.py	Fri Nov 12 16:29:24 2010
@@ -144,30 +144,44 @@
 
 # ____________________________________________________________
 
-_callinfo_for_oopspec = {} # {oopspecindex: (calldescr, func_as_int)}
-
-def callinfo_for_oopspec(oopspecindex):
-    """A function that returns the calldescr and the function
-    address (as an int) of one of the OS_XYZ functions defined above.
-    Don't use this if there might be several implementations of the same
-    OS_XYZ specialized by type, e.g. OS_ARRAYCOPY."""
-    try:
-        return _callinfo_for_oopspec[oopspecindex]
-    except KeyError:
-        return (None, 0)
-
-
-def _funcptr_for_oopspec_memo(oopspecindex):
-    from pypy.jit.codewriter import heaptracker
-    _, func_as_int = callinfo_for_oopspec(oopspecindex)
-    funcadr = heaptracker.int2adr(func_as_int)
-    return funcadr.ptr
-_funcptr_for_oopspec_memo._annspecialcase_ = 'specialize:memo'
-
-def funcptr_for_oopspec(oopspecindex):
-    """A memo function that returns a pointer to the function described
-    by OS_XYZ (as a real low-level function pointer)."""
-    funcptr = _funcptr_for_oopspec_memo(oopspecindex)
-    assert funcptr
-    return funcptr
-funcptr_for_oopspec._annspecialcase_ = 'specialize:arg(0)'
+class CallInfoCollection(object):
+    def __init__(self):
+        # {oopspecindex: (calldescr, func_as_int)}
+        self._callinfo_for_oopspec = {}
+
+    def _freeze_(self):
+        return True
+
+    def add(self, oopspecindex, calldescr, func_as_int):
+        self._callinfo_for_oopspec[oopspecindex] = calldescr, func_as_int
+
+    def has_oopspec(self, oopspecindex):
+        return oopspecindex in self._callinfo_for_oopspec
+
+    def all_function_addresses_as_int(self):
+        return [func for (_, func) in self._callinfo_for_oopspec.values()]
+
+    def callinfo_for_oopspec(self, oopspecindex):
+        """A function that returns the calldescr and the function
+        address (as an int) of one of the OS_XYZ functions defined above.
+        Don't use this if there might be several implementations of the same
+        OS_XYZ specialized by type, e.g. OS_ARRAYCOPY."""
+        try:
+            return self._callinfo_for_oopspec[oopspecindex]
+        except KeyError:
+            return (None, 0)
+
+    def _funcptr_for_oopspec_memo(self, oopspecindex):
+        from pypy.jit.codewriter import heaptracker
+        _, func_as_int = self.callinfo_for_oopspec(oopspecindex)
+        funcadr = heaptracker.int2adr(func_as_int)
+        return funcadr.ptr
+    _funcptr_for_oopspec_memo._annspecialcase_ = 'specialize:memo'
+
+    def funcptr_for_oopspec(self, oopspecindex):
+        """A memo function that returns a pointer to the function described
+        by OS_XYZ (as a real low-level function pointer)."""
+        funcptr = self._funcptr_for_oopspec_memo(oopspecindex)
+        assert funcptr
+        return funcptr
+    funcptr_for_oopspec._annspecialcase_ = 'specialize:arg(1)'

Modified: pypy/branch/fast-forward/pypy/jit/codewriter/jtransform.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/codewriter/jtransform.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/codewriter/jtransform.py	Fri Nov 12 16:29:24 2010
@@ -6,7 +6,7 @@
 from pypy.objspace.flow.model import Block, Link, c_last_exception
 from pypy.jit.codewriter.flatten import ListOfKind, IndirectCallTargets
 from pypy.jit.codewriter import support, heaptracker
-from pypy.jit.codewriter.effectinfo import EffectInfo, _callinfo_for_oopspec
+from pypy.jit.codewriter.effectinfo import EffectInfo
 from pypy.jit.codewriter.policy import log
 from pypy.jit.metainterp.typesystem import deref, arrayItem
 from pypy.rlib import objectmodel
@@ -1084,7 +1084,8 @@
         else:
             func = heaptracker.adr2int(
                 llmemory.cast_ptr_to_adr(op.args[0].value))
-            _callinfo_for_oopspec[oopspecindex] = calldescr, func
+            self.callcontrol.callinfocollection.add(oopspecindex,
+                                                    calldescr, func)
         op1 = self.rewrite_call(op, 'residual_call',
                                 [op.args[0], calldescr],
                                 args=args)
@@ -1095,7 +1096,7 @@
     def _register_extra_helper(self, oopspecindex, oopspec_name,
                                argtypes, resulttype):
         # a bit hackish
-        if oopspecindex in _callinfo_for_oopspec:
+        if self.callcontrol.callinfocollection.has_oopspec(oopspecindex):
             return
         c_func, TP = support.builtin_func_for_spec(self.cpu.rtyper,
                                                    oopspec_name, argtypes,
@@ -1109,7 +1110,7 @@
         else:
             func = heaptracker.adr2int(
                 llmemory.cast_ptr_to_adr(c_func.value))
-        _callinfo_for_oopspec[oopspecindex] = calldescr, func
+        self.callcontrol.callinfocollection.add(oopspecindex, calldescr, func)
 
     def _handle_stroruni_call(self, op, oopspec_name, args):
         SoU = args[0].concretetype     # Ptr(STR) or Ptr(UNICODE)

Modified: pypy/branch/fast-forward/pypy/jit/codewriter/test/test_jtransform.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/codewriter/test/test_jtransform.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/codewriter/test/test_jtransform.py	Fri Nov 12 16:29:24 2010
@@ -74,7 +74,20 @@
     def calldescr_canraise(self, calldescr):
         return False
 
+class FakeCallInfoCollection:
+    def __init__(self):
+        self.seen = []
+    def add(self, oopspecindex, calldescr, func):
+        self.seen.append((oopspecindex, calldescr, func))
+    def has_oopspec(self, oopspecindex):
+        for i, c, f in self.seen:
+            if i == oopspecindex:
+                return True
+        return False
+
 class FakeBuiltinCallControl:
+    def __init__(self):
+        self.callinfocollection = FakeCallInfoCollection()
     def guess_call_kind(self, op):
         return 'builtin'
     def getcalldescr(self, op, oopspecindex=None):
@@ -810,7 +823,8 @@
     v2 = varoftype(PSTR)
     v3 = varoftype(PSTR)
     op = SpaceOperation('direct_call', [const(func), v1, v2], v3)
-    tr = Transformer(FakeCPU(), FakeBuiltinCallControl())
+    cc = FakeBuiltinCallControl()
+    tr = Transformer(FakeCPU(), cc)
     op1 = tr.rewrite_operation(op)
     assert op1.opname == 'residual_call_r_r'
     assert op1.args[0].value == func
@@ -819,9 +833,10 @@
     assert op1.result == v3
     #
     # check the callinfo_for_oopspec
-    got = effectinfo.callinfo_for_oopspec(effectinfo.EffectInfo.OS_UNI_CONCAT)
-    assert got[0] == op1.args[1]    # the calldescr
-    assert heaptracker.int2adr(got[1]) == llmemory.cast_ptr_to_adr(func)
+    got = cc.callinfocollection.seen[0]
+    assert got[0] == effectinfo.EffectInfo.OS_UNI_CONCAT
+    assert got[1] == op1.args[1]    # the calldescr
+    assert heaptracker.int2adr(got[2]) == llmemory.cast_ptr_to_adr(func)
 
 def test_str_slice():
     # test that the oopspec is present and correctly transformed
@@ -893,7 +908,8 @@
     v2 = varoftype(PUNICODE)
     v3 = varoftype(lltype.Bool)
     op = SpaceOperation('direct_call', [const(func), v1, v2], v3)
-    tr = Transformer(FakeCPU(), FakeBuiltinCallControl())
+    cc = FakeBuiltinCallControl()
+    tr = Transformer(FakeCPU(), cc)
     op1 = tr.rewrite_operation(op)
     assert op1.opname == 'residual_call_r_i'
     assert op1.args[0].value == func
@@ -901,9 +917,9 @@
     assert op1.args[2] == ListOfKind('ref', [v1, v2])
     assert op1.result == v3
     # test that the OS_UNIEQ_* functions are registered
-    cifo = effectinfo._callinfo_for_oopspec
-    assert effectinfo.EffectInfo.OS_UNIEQ_SLICE_NONNULL in cifo
-    assert effectinfo.EffectInfo.OS_UNIEQ_CHECKNULL_CHAR in cifo
+    cic = cc.callinfocollection
+    assert cic.has_oopspec(effectinfo.EffectInfo.OS_UNIEQ_SLICE_NONNULL)
+    assert cic.has_oopspec(effectinfo.EffectInfo.OS_UNIEQ_CHECKNULL_CHAR)
 
 def test_list_ll_arraycopy():
     from pypy.rlib.rgc import ll_arraycopy

Modified: pypy/branch/fast-forward/pypy/jit/metainterp/optimizeopt/optimizer.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/metainterp/optimizeopt/optimizer.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/metainterp/optimizeopt/optimizer.py	Fri Nov 12 16:29:24 2010
@@ -66,10 +66,10 @@
         assert isinstance(constbox, Const)
         self.box = constbox
         self.level = LEVEL_CONSTANT
-        try:
-            val = self.box.getint()
+        if isinstance(constbox, ConstInt):
+            val = constbox.getint()
             self.intbound = IntBound(val, val)
-        except NotImplementedError:
+        else:
             self.intbound = IntUnbounded()
 
     def get_constant_class(self, cpu):

Modified: pypy/branch/fast-forward/pypy/jit/metainterp/optimizeopt/string.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/metainterp/optimizeopt/string.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/metainterp/optimizeopt/string.py	Fri Nov 12 16:29:24 2010
@@ -9,7 +9,7 @@
 from pypy.jit.metainterp.optimizeopt.optimizer import CONST_0, CONST_1
 from pypy.jit.metainterp.optimizeopt.optimizer import llhelper
 from pypy.jit.metainterp.optimizeutil import _findall
-from pypy.jit.codewriter.effectinfo import EffectInfo, callinfo_for_oopspec
+from pypy.jit.codewriter.effectinfo import EffectInfo
 from pypy.jit.codewriter import heaptracker
 from pypy.rlib.unroll import unrolling_iterable
 from pypy.rlib.objectmodel import specialize, we_are_translated
@@ -593,7 +593,8 @@
 
     def generate_modified_call(self, oopspecindex, args, result, mode):
         oopspecindex += mode.OS_offset
-        calldescr, func = callinfo_for_oopspec(oopspecindex)
+        cic = self.optimizer.metainterp_sd.callinfocollection
+        calldescr, func = cic.callinfo_for_oopspec(oopspecindex)
         op = ResOperation(rop.CALL, [ConstInt(func)] + args, result,
                           descr=calldescr)
         self.optimizer.newoperations.append(op)

Modified: pypy/branch/fast-forward/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/metainterp/pyjitpl.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/metainterp/pyjitpl.py	Fri Nov 12 16:29:24 2010
@@ -1261,6 +1261,7 @@
         #
         self.jitdrivers_sd = codewriter.callcontrol.jitdrivers_sd
         self.virtualref_info = codewriter.callcontrol.virtualref_info
+        self.callinfocollection = codewriter.callcontrol.callinfocollection
         self.setup_jitdrivers_sd(optimizer)
         #
         # store this information for fastpath of call_assembler
@@ -1624,7 +1625,7 @@
         assert jitdriver_sd is self.jitdriver_sd
         self.create_empty_history()
         try:
-            original_boxes = self.initialize_original_boxes(jitdriver_sd,*args)
+            original_boxes = self.initialize_original_boxes(jitdriver_sd, *args)
             return self._compile_and_run_once(original_boxes)
         finally:
             self.staticdata.profiler.end_tracing()

Modified: pypy/branch/fast-forward/pypy/jit/metainterp/resume.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/metainterp/resume.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/metainterp/resume.py	Fri Nov 12 16:29:24 2010
@@ -4,8 +4,7 @@
 from pypy.jit.metainterp.history import INT, REF, FLOAT, HOLE
 from pypy.jit.metainterp.resoperation import rop
 from pypy.jit.metainterp import jitprof
-from pypy.jit.codewriter.effectinfo import EffectInfo, callinfo_for_oopspec
-from pypy.jit.codewriter.effectinfo import funcptr_for_oopspec
+from pypy.jit.codewriter.effectinfo import EffectInfo
 from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rstr
 from pypy.rlib import rarithmetic
 from pypy.rlib.objectmodel import we_are_translated, specialize
@@ -774,14 +773,16 @@
                                            strbox, ConstInt(index), charbox)
 
     def concat_strings(self, str1num, str2num):
-        calldescr, func = callinfo_for_oopspec(EffectInfo.OS_STR_CONCAT)
+        cic = self.metainterp.staticdata.callinfocollection
+        calldescr, func = cic.callinfo_for_oopspec(EffectInfo.OS_STR_CONCAT)
         str1box = self.decode_box(str1num, REF)
         str2box = self.decode_box(str2num, REF)
         return self.metainterp.execute_and_record_varargs(
             rop.CALL, [ConstInt(func), str1box, str2box], calldescr)
 
     def slice_string(self, strnum, startnum, lengthnum):
-        calldescr, func = callinfo_for_oopspec(EffectInfo.OS_STR_SLICE)
+        cic = self.metainterp.staticdata.callinfocollection
+        calldescr, func = cic.callinfo_for_oopspec(EffectInfo.OS_STR_SLICE)
         strbox = self.decode_box(strnum, REF)
         startbox = self.decode_box(startnum, INT)
         lengthbox = self.decode_box(lengthnum, INT)
@@ -800,14 +801,16 @@
                                            strbox, ConstInt(index), charbox)
 
     def concat_unicodes(self, str1num, str2num):
-        calldescr, func = callinfo_for_oopspec(EffectInfo.OS_UNI_CONCAT)
+        cic = self.metainterp.staticdata.callinfocollection
+        calldescr, func = cic.callinfo_for_oopspec(EffectInfo.OS_UNI_CONCAT)
         str1box = self.decode_box(str1num, REF)
         str2box = self.decode_box(str2num, REF)
         return self.metainterp.execute_and_record_varargs(
             rop.CALL, [ConstInt(func), str1box, str2box], calldescr)
 
     def slice_unicode(self, strnum, startnum, lengthnum):
-        calldescr, func = callinfo_for_oopspec(EffectInfo.OS_UNI_SLICE)
+        cic = self.metainterp.staticdata.callinfocollection
+        calldescr, func = cic.callinfo_for_oopspec(EffectInfo.OS_UNI_SLICE)
         strbox = self.decode_box(strnum, REF)
         startbox = self.decode_box(startnum, INT)
         lengthbox = self.decode_box(lengthnum, INT)
@@ -903,8 +906,8 @@
 
 def blackhole_from_resumedata(blackholeinterpbuilder, jitdriver_sd, storage,
                               all_virtuals=None):
-    resumereader = ResumeDataDirectReader(blackholeinterpbuilder.cpu, storage,
-                                          all_virtuals)
+    resumereader = ResumeDataDirectReader(blackholeinterpbuilder.metainterp_sd,
+                                          storage, all_virtuals)
     vinfo = jitdriver_sd.virtualizable_info
     ginfo = jitdriver_sd.greenfield_info
     vrefinfo = blackholeinterpbuilder.metainterp_sd.virtualref_info
@@ -939,7 +942,7 @@
     return firstbh
 
 def force_from_resumedata(metainterp_sd, storage, vinfo, ginfo):
-    resumereader = ResumeDataDirectReader(metainterp_sd.cpu, storage)
+    resumereader = ResumeDataDirectReader(metainterp_sd, storage)
     resumereader.handling_async_forcing()
     vrefinfo = metainterp_sd.virtualref_info
     resumereader.consume_vref_and_vable(vrefinfo, vinfo, ginfo)
@@ -953,8 +956,9 @@
     #             1: in handle_async_forcing
     #             2: resuming from the GUARD_NOT_FORCED
 
-    def __init__(self, cpu, storage, all_virtuals=None):
-        self._init(cpu, storage)
+    def __init__(self, metainterp_sd, storage, all_virtuals=None):
+        self._init(metainterp_sd.cpu, storage)
+        self.callinfocollection = metainterp_sd.callinfocollection
         if all_virtuals is None:        # common case
             self._prepare(storage)
         else:
@@ -1047,7 +1051,8 @@
         str2 = self.decode_ref(str2num)
         str1 = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), str1)
         str2 = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), str2)
-        funcptr = funcptr_for_oopspec(EffectInfo.OS_STR_CONCAT)
+        cic = self.callinfocollection
+        funcptr = cic.funcptr_for_oopspec(EffectInfo.OS_STR_CONCAT)
         result = funcptr(str1, str2)
         return lltype.cast_opaque_ptr(llmemory.GCREF, result)
 
@@ -1056,7 +1061,8 @@
         start = self.decode_int(startnum)
         length = self.decode_int(lengthnum)
         str = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), str)
-        funcptr = funcptr_for_oopspec(EffectInfo.OS_STR_SLICE)
+        cic = self.callinfocollection
+        funcptr = cic.funcptr_for_oopspec(EffectInfo.OS_STR_SLICE)
         result = funcptr(str, start, start + length)
         return lltype.cast_opaque_ptr(llmemory.GCREF, result)
 
@@ -1072,7 +1078,8 @@
         str2 = self.decode_ref(str2num)
         str1 = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), str1)
         str2 = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), str2)
-        funcptr = funcptr_for_oopspec(EffectInfo.OS_UNI_CONCAT)
+        cic = self.callinfocollection
+        funcptr = cic.funcptr_for_oopspec(EffectInfo.OS_UNI_CONCAT)
         result = funcptr(str1, str2)
         return lltype.cast_opaque_ptr(llmemory.GCREF, result)
 
@@ -1081,7 +1088,8 @@
         start = self.decode_int(startnum)
         length = self.decode_int(lengthnum)
         str = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), str)
-        funcptr = funcptr_for_oopspec(EffectInfo.OS_UNI_SLICE)
+        cic = self.callinfocollection
+        funcptr = cic.funcptr_for_oopspec(EffectInfo.OS_UNI_SLICE)
         result = funcptr(str, start, start + length)
         return lltype.cast_opaque_ptr(llmemory.GCREF, result)
 

Modified: pypy/branch/fast-forward/pypy/jit/metainterp/test/test_del.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/metainterp/test/test_del.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/metainterp/test/test_del.py	Fri Nov 12 16:29:24 2010
@@ -85,6 +85,7 @@
     def test_signal_action(self):
         from pypy.module.signal.interp_signal import SignalActionFlag
         action = SignalActionFlag()
+        action.has_bytecode_counter = True
         #
         myjitdriver = JitDriver(greens = [], reds = ['n', 'x'])
         class X:
@@ -92,17 +93,17 @@
         #
         def f(n):
             x = X()
-            while n > 0:
+            action.reset_ticker(n)
+            while True:
                 myjitdriver.can_enter_jit(n=n, x=x)
                 myjitdriver.jit_merge_point(n=n, x=x)
                 x.foo = n
                 n -= 1
-                if action.get() != 0:
+                if action.decrement_ticker(1) < 0:
                     break
-                action.set(0)
             return 42
         self.meta_interp(f, [20])
-        self.check_loops(getfield_raw=1, call=0, call_pure=0)
+        self.check_loops(getfield_raw=1, setfield_raw=1, call=0, call_pure=0)
 
 class TestOOtype(DelTests, OOJitMixin):
     def setup_class(cls):

Modified: pypy/branch/fast-forward/pypy/jit/metainterp/test/test_optimizeopt.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/metainterp/test/test_optimizeopt.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/metainterp/test/test_optimizeopt.py	Fri Nov 12 16:29:24 2010
@@ -264,6 +264,8 @@
         metainterp_sd = FakeMetaInterpStaticData(self.cpu)
         if hasattr(self, 'vrefinfo'):
             metainterp_sd.virtualref_info = self.vrefinfo
+        if hasattr(self, 'callinfocollection'):
+            metainterp_sd.callinfocollection = self.callinfocollection
         optimize_loop_1(metainterp_sd, loop)
         #
         expected = self.parse(optops)
@@ -4180,22 +4182,20 @@
     # ----------
     def optimize_strunicode_loop_extradescrs(self, ops, spectext, optops):
         from pypy.jit.metainterp.optimizeopt import string
-        def my_callinfo_for_oopspec(oopspecindex):
-            calldescrtype = type(LLtypeMixin.strequaldescr)
-            for value in LLtypeMixin.__dict__.values():
-                if isinstance(value, calldescrtype):
-                    if (value.get_extra_info() and
-                        value.get_extra_info().oopspecindex == oopspecindex):
-                        # returns 0 for 'func' in this test
-                        return value, 0
-            raise AssertionError("not found: oopspecindex=%d" % oopspecindex)
+        class FakeCallInfoCollection:
+            def callinfo_for_oopspec(self, oopspecindex):
+                calldescrtype = type(LLtypeMixin.strequaldescr)
+                for value in LLtypeMixin.__dict__.values():
+                    if isinstance(value, calldescrtype):
+                        extra = value.get_extra_info()
+                        if extra and extra.oopspecindex == oopspecindex:
+                            # returns 0 for 'func' in this test
+                            return value, 0
+                raise AssertionError("not found: oopspecindex=%d" %
+                                     oopspecindex)
         #
-        saved = string.callinfo_for_oopspec
-        try:
-            string.callinfo_for_oopspec = my_callinfo_for_oopspec
-            self.optimize_strunicode_loop(ops, spectext, optops)
-        finally:
-            string.callinfo_for_oopspec = saved
+        self.callinfocollection = FakeCallInfoCollection()
+        self.optimize_strunicode_loop(ops, spectext, optops)
 
     def test_str_equal_noop1(self):
         ops = """

Modified: pypy/branch/fast-forward/pypy/jit/metainterp/test/test_resume.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/metainterp/test/test_resume.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/metainterp/test/test_resume.py	Fri Nov 12 16:29:24 2010
@@ -51,6 +51,7 @@
 
 class MyMetaInterp:
     _already_allocated_resume_virtuals = None
+    callinfocollection = None
 
     def __init__(self, cpu=None):
         if cpu is None:
@@ -156,12 +157,12 @@
     storage.rd_numb = numb
     #
     cpu = MyCPU([42, gcref1, -66])
-    reader = ResumeDataDirectReader(cpu, storage)
+    metainterp = MyMetaInterp(cpu)
+    reader = ResumeDataDirectReader(metainterp, storage)
     _next_section(reader, 42, 111, gcrefnull, 42, gcref1)
     _next_section(reader, 222, 333)
     _next_section(reader, 42, gcref1, -66)
     #
-    metainterp = MyMetaInterp(cpu)
     reader = ResumeDataBoxReader(storage, metainterp)
     bi, br, bf = [None]*3, [None]*2, [None]*0
     info = MyBlackholeInterp([lltype.Signed, lltype.Signed,
@@ -193,7 +194,7 @@
     storage.rd_numb = numb
     #
     cpu = MyCPU([])
-    reader = ResumeDataDirectReader(cpu, storage)
+    reader = ResumeDataDirectReader(MyMetaInterp(cpu), storage)
     _next_section(reader, 100)
 
 
@@ -211,7 +212,7 @@
     class FakeMetainterp(object):
         _already_allocated_resume_virtuals = None
         cpu = None
-    reader = ResumeDataDirectReader(None, FakeStorage())
+    reader = ResumeDataDirectReader(MyMetaInterp(None), FakeStorage())
     assert reader.force_all_virtuals() == ["allocated", reader.virtual_default]
 
 # ____________________________________________________________
@@ -925,7 +926,7 @@
     liveboxes = modifier.finish({})
     assert storage.rd_snapshot is None
     cpu = MyCPU([])
-    reader = ResumeDataDirectReader(cpu, storage)
+    reader = ResumeDataDirectReader(MyMetaInterp(cpu), storage)
     _next_section(reader, sys.maxint, 2**16, -65)
     _next_section(reader, 2, 3)
     _next_section(reader, sys.maxint, 1, sys.maxint, 2**16)

Modified: pypy/branch/fast-forward/pypy/jit/metainterp/test/test_virtualref.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/metainterp/test/test_virtualref.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/metainterp/test/test_virtualref.py	Fri Nov 12 16:29:24 2010
@@ -88,7 +88,11 @@
         cpu.get_latest_value_int = lambda i:guard_op.getfailargs()[i].getint()
         cpu.get_latest_value_ref = lambda i:guard_op.getfailargs()[i].getref_base()
         cpu.clear_latest_values = lambda count: None
-        resumereader = ResumeDataDirectReader(cpu, guard_op.getdescr())
+        class FakeMetaInterpSd:
+            callinfocollection = None
+        FakeMetaInterpSd.cpu = cpu
+        resumereader = ResumeDataDirectReader(FakeMetaInterpSd(),
+                                              guard_op.getdescr())
         vrefinfo = self.metainterp.staticdata.virtualref_info
         lst = []
         vrefinfo.continue_tracing = lambda vref, virtual: \

Modified: pypy/branch/fast-forward/pypy/jit/tool/pypytrace-mode.el
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/tool/pypytrace-mode.el	(original)
+++ pypy/branch/fast-forward/pypy/jit/tool/pypytrace-mode.el	Fri Nov 12 16:29:24 2010
@@ -26,7 +26,7 @@
     ("<.*FieldDescr \\([^ ]*\\)" (1 'font-lock-variable-name-face))
     ;; comment out debug_merge_point, but then highlight specific part of it
     ("^debug_merge_point.*" . font-lock-comment-face)
-    ("^\\(debug_merge_point\\).*code object\\(.*\\), file \\('.*'\\), \\(line .*\\)> \\(.*\\)')"
+    ("^\\(debug_merge_point\\).*code object\\(.*\\), file \\('.*'\\), \\(line .*\\)> \\(.*\\)"
      (1 'compilation-warning t)
      (2 'escape-glyph t)
      (3 'font-lock-string-face t)

Modified: pypy/branch/fast-forward/pypy/module/cpyext/api.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/cpyext/api.py	(original)
+++ pypy/branch/fast-forward/pypy/module/cpyext/api.py	Fri Nov 12 16:29:24 2010
@@ -226,7 +226,7 @@
             def unwrapper(space, *args):
                 from pypy.module.cpyext.pyobject import Py_DecRef
                 from pypy.module.cpyext.pyobject import make_ref, from_ref
-                from pypy.module.cpyext.pyobject import BorrowPair
+                from pypy.module.cpyext.pyobject import Reference
                 newargs = ()
                 to_decref = []
                 assert len(args) == len(api_function.argtypes)
@@ -270,8 +270,8 @@
                             return api_function.error_value
                     if res is None:
                         return None
-                    elif isinstance(res, BorrowPair):
-                        return res.w_borrowed
+                    elif isinstance(res, Reference):
+                        return res.get_wrapped(space)
                     else:
                         return res
                 finally:
@@ -478,7 +478,7 @@
     @specialize.ll()
     def wrapper(*args):
         from pypy.module.cpyext.pyobject import make_ref, from_ref
-        from pypy.module.cpyext.pyobject import BorrowPair
+        from pypy.module.cpyext.pyobject import Reference
         # we hope that malloc removal removes the newtuple() that is
         # inserted exactly here by the varargs specializer
         llop.gc_stack_bottom(lltype.Void)   # marker for trackgcroot.py
@@ -530,7 +530,7 @@
             elif is_PyObject(callable.api_func.restype):
                 if result is None:
                     retval = make_ref(space, None)
-                elif isinstance(result, BorrowPair):
+                elif isinstance(result, Reference):
                     retval = result.get_ref(space)
                 elif not rffi._isllptr(result):
                     retval = rffi.cast(callable.api_func.restype,

Modified: pypy/branch/fast-forward/pypy/module/cpyext/pyobject.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/cpyext/pyobject.py	(original)
+++ pypy/branch/fast-forward/pypy/module/cpyext/pyobject.py	Fri Nov 12 16:29:24 2010
@@ -424,7 +424,18 @@
     state = space.fromcache(RefcountState)
     return state.make_borrowed(w_container, w_borrowed)
 
-class BorrowPair:
+class Reference:
+    def __init__(self, pyobj):
+        assert not isinstance(pyobj, W_Root)
+        self.pyobj = pyobj
+
+    def get_ref(self, space):
+        return self.pyobj
+
+    def get_wrapped(self, space):
+        return from_ref(space, self.pyobj)
+
+class BorrowPair(Reference):
     """
     Delays the creation of a borrowed reference.
     """
@@ -435,6 +446,9 @@
     def get_ref(self, space):
         return make_borrowed_ref(space, self.w_container, self.w_borrowed)
 
+    def get_wrapped(self, space):
+        return self.w_borrowed
+
 def borrow_from(container, borrowed):
     return BorrowPair(container, borrowed)
 

Modified: pypy/branch/fast-forward/pypy/module/posix/interp_posix.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/posix/interp_posix.py	(original)
+++ pypy/branch/fast-forward/pypy/module/posix/interp_posix.py	Fri Nov 12 16:29:24 2010
@@ -462,7 +462,8 @@
         self.w_environ = space.newdict()
         if _WIN:
             self.cryptProviderPtr = lltype.malloc(
-                rffi.CArray(HCRYPTPROV), 1, zero=True, flavor='raw')
+                rffi.CArray(HCRYPTPROV), 1, zero=True,
+                flavor='raw', immortal=True)
     def startup(self, space):
         _convertenviron(space, self.w_environ)
     def _freeze_(self):

Modified: pypy/branch/fast-forward/pypy/objspace/flow/objspace.py
==============================================================================
--- pypy/branch/fast-forward/pypy/objspace/flow/objspace.py	(original)
+++ pypy/branch/fast-forward/pypy/objspace/flow/objspace.py	Fri Nov 12 16:29:24 2010
@@ -213,6 +213,11 @@
             check_class = self.unwrap(w_check_class)
         except UnwrapException:
             raise Exception, "non-constant except guard"
+        if check_class in (NotImplementedError, AssertionError):
+            # if we are in geninterp, we cannot catch these exceptions
+            if not self.config.translation.builtins_can_raise_exceptions:
+                raise error.FlowingError("Catching %s is not valid in RPython" %
+                                         check_class.__name__)
         if not isinstance(check_class, tuple):
             # the simple case
             return ObjSpace.exception_match(self, w_exc_type, w_check_class)

Modified: pypy/branch/fast-forward/pypy/objspace/flow/test/test_objspace.py
==============================================================================
--- pypy/branch/fast-forward/pypy/objspace/flow/test/test_objspace.py	(original)
+++ pypy/branch/fast-forward/pypy/objspace/flow/test/test_objspace.py	Fri Nov 12 16:29:24 2010
@@ -5,7 +5,7 @@
 from pypy.objspace.flow.model import flatten, mkentrymap, c_last_exception
 from pypy.interpreter.argument import Arguments
 from pypy.translator.simplify import simplify_graph
-from pypy.objspace.flow.objspace import FlowObjSpace 
+from pypy.objspace.flow.objspace import FlowObjSpace, error
 from pypy.objspace.flow import objspace, flowcontext
 from pypy import conftest
 from pypy.tool.stdlib_opcode import bytecode_spec
@@ -954,6 +954,22 @@
                 assert op.args[0] == Constant(g)
 
 
+    def test_cannot_catch_special_exceptions(self):
+        def f():
+            try:
+                f()
+            except NotImplementedError:
+                pass
+        py.test.raises(error.FlowingError, "self.codetest(f)")
+        #
+        def f():
+            try:
+                f()
+            except AssertionError:
+                pass
+        py.test.raises(error.FlowingError, "self.codetest(f)")
+
+
 class TestFlowObjSpaceDelay(Base):
     def setup_class(cls):
         cls.space = FlowObjSpace()
@@ -1014,6 +1030,15 @@
         expected.sort()
         assert excfound == expected
 
+    def test_can_catch_special_exceptions(self):
+        def f():
+            try:
+                f()
+            except NotImplementedError:
+                pass
+        graph = self.codetest(f)
+        # assert did not crash
+
 
 DATA = {'x': 5,
         'y': 6}

Modified: pypy/branch/fast-forward/pypy/rlib/rarithmetic.py
==============================================================================
--- pypy/branch/fast-forward/pypy/rlib/rarithmetic.py	(original)
+++ pypy/branch/fast-forward/pypy/rlib/rarithmetic.py	Fri Nov 12 16:29:24 2010
@@ -614,6 +614,12 @@
     def __cmp__(self, other):
         raise TypeError("not supported on r_singlefloat instances")
 
+    def __eq__(self, other):
+        return self.__class__ is other.__class__ and self._bytes == other._bytes
+
+    def __ne__(self, other):
+        return not self.__eq__(other)
+
 class r_longfloat(object):
     """A value of the C type 'long double'.
 
@@ -632,6 +638,11 @@
     def __cmp__(self, other):
         raise TypeError("not supported on r_longfloat instances")
 
+    def __eq__(self, other):
+        return self.__class__ is other.__class__ and self.value == other.value
+
+    def __ne__(self, other):
+        return not self.__eq__(other)
 
 
 class For_r_singlefloat_values_Entry(extregistry.ExtRegistryEntry):

Modified: pypy/branch/fast-forward/pypy/rlib/streamio.py
==============================================================================
--- pypy/branch/fast-forward/pypy/rlib/streamio.py	(original)
+++ pypy/branch/fast-forward/pypy/rlib/streamio.py	Fri Nov 12 16:29:24 2010
@@ -12,7 +12,7 @@
   * some other methods also have no default parameters.
   * close() should be called exactly once and no further operations performed;
     there is no __del__() closing the stream for you.
-  * some methods may raise NotImplementedError.
+  * some methods may raise MyNotImplementedError.
   * peek() returns some (or no) characters that have already been read ahead.
   * flushable() returns True/False if flushing that stream is useful/pointless.
 
@@ -54,6 +54,12 @@
            ('a', True):  O_RDWR   | O_CREAT,
            }
 
+class MyNotImplementedError(Exception):
+    """
+    Catching NotImplementedError is not RPython, so we use this custom class
+    instead of it
+    """
+
 # ____________________________________________________________
 
 
@@ -210,16 +216,16 @@
     some methods."""
 
     def read(self, n):
-        raise NotImplementedError
+        raise MyNotImplementedError
 
     def write(self, data):
-        raise NotImplementedError
+        raise MyNotImplementedError
 
     def tell(self):
-        raise NotImplementedError
+        raise MyNotImplementedError
 
     def seek(self, offset, whence):
-        raise NotImplementedError
+        raise MyNotImplementedError
 
     def readall(self):
         bufsize = 8192
@@ -252,7 +258,7 @@
         return ''.join(result)
 
     def truncate(self, size):
-        raise NotImplementedError
+        raise MyNotImplementedError
 
     def flush_buffers(self):
         pass
@@ -488,7 +494,7 @@
         if self.lines or self.buf:
             try:
                 self.do_seek(self.tell(), 0)
-            except NotImplementedError:
+            except MyNotImplementedError:
                 pass
             else:
                 self.lines = []
@@ -536,14 +542,14 @@
             self.buf = ""
             try:
                 self.do_seek(offset, 1)
-            except NotImplementedError:
+            except MyNotImplementedError:
                 intoffset = offset2int(offset)
                 self.read(intoffset)
             return
         if whence == 2:
             try:
                 self.do_seek(offset, 2)
-            except NotImplementedError:
+            except MyNotImplementedError:
                 pass
             else:
                 self.lines = []
@@ -1020,7 +1026,7 @@
         if self.buf:
             try:
                 self.base.seek(-len(self.buf), 1)
-            except NotImplementedError:
+            except MyNotImplementedError:
                 pass
             else:
                 self.buf = ""

Modified: pypy/branch/fast-forward/pypy/rlib/test/test_rarithmetic.py
==============================================================================
--- pypy/branch/fast-forward/pypy/rlib/test/test_rarithmetic.py	(original)
+++ pypy/branch/fast-forward/pypy/rlib/test/test_rarithmetic.py	Fri Nov 12 16:29:24 2010
@@ -325,6 +325,15 @@
     assert float(x) != 2.1
     assert abs(float(x) - 2.1) < 1E-6
 
+def test_r_singlefloat_eq():
+    x = r_singlefloat(2.5)       # exact number
+    y = r_singlefloat(2.5)
+    assert x == y
+    assert not x != y
+    assert not x == 2.5
+    assert x != 2.5
+    py.test.raises(TypeError, "x>y")
+
 class BaseTestRarithmetic(BaseRtypingTest):
     def test_formatd(self):
         from pypy.rlib.rarithmetic import formatd
@@ -358,7 +367,17 @@
         assert res == 1.0
 
         res = self.interpret(f, [1])
-        assert res == 1e-100                 
+        assert res == 1e-100
+
+    def test_compare_singlefloat_crashes(self):
+        from pypy.rlib.rarithmetic import r_singlefloat
+        from pypy.rpython.error import MissingRTypeOperation
+        def f(x):
+            a = r_singlefloat(x)
+            b = r_singlefloat(x+1)
+            return a == b
+        py.test.raises(MissingRTypeOperation, "self.interpret(f, [42.0])")
+
 
 class TestLLtype(BaseTestRarithmetic, LLRtypeMixin):
     pass

Modified: pypy/branch/fast-forward/pypy/rpython/memory/gc/base.py
==============================================================================
--- pypy/branch/fast-forward/pypy/rpython/memory/gc/base.py	(original)
+++ pypy/branch/fast-forward/pypy/rpython/memory/gc/base.py	Fri Nov 12 16:29:24 2010
@@ -247,6 +247,21 @@
                 (not self.config.taggedpointers or
                  llmemory.cast_adr_to_int(addr) & 1 == 0))
 
+    def enumerate_all_roots(self, callback, arg):
+        """For each root object, invoke callback(obj, arg).
+        'callback' should not be a bound method.
+        Note that this method is not suitable for actually doing the
+        collection in a moving GC, because you cannot write back a
+        modified address.  It is there only for inspection.
+        """
+        # overridden in some subclasses, for GCs which have an additional
+        # list of last generation roots
+        callback2, attrname = _convert_callback_formats(callback)    # :-/
+        setattr(self, attrname, arg)
+        self.root_walker.walk_roots(callback2, callback2, callback2)
+        self.run_finalizers.foreach(callback, arg)
+    enumerate_all_roots._annspecialcase_ = 'specialize:arg(1)'
+
     def debug_check_consistency(self):
         """To use after a collection.  If self.DEBUG is set, this
         enumerates all roots and traces all objects to check if we didn't
@@ -260,8 +275,7 @@
             self._debug_pending = self.AddressStack()
             if not we_are_translated():
                 self.root_walker._walk_prebuilt_gc(self._debug_record)
-            callback = GCBase._debug_callback
-            self.root_walker.walk_roots(callback, callback, callback)
+            self.enumerate_all_roots(GCBase._debug_callback, self)
             pending = self._debug_pending
             while pending.non_empty():
                 obj = pending.pop()
@@ -275,9 +289,8 @@
             seen.add(obj)
             self.debug_check_object(obj)
             self._debug_pending.append(obj)
-    def _debug_callback(self, root):
-        obj = root.address[0]
-        ll_assert(bool(obj), "NULL address from walk_roots()")
+    @staticmethod
+    def _debug_callback(obj, self):
         self._debug_record(obj)
     def _debug_callback2(self, pointer, ignored):
         obj = pointer.address[0]
@@ -432,3 +445,17 @@
     if factor != 1:
         return 0.0
     return value
+
+def _convert_callback_formats(callback):
+    callback = getattr(callback, 'im_func', callback)
+    if callback not in _converted_callback_formats:
+        def callback2(gc, root):
+            obj = root.address[0]
+            ll_assert(bool(obj), "NULL address from walk_roots()")
+            callback(obj, getattr(gc, attrname))
+        attrname = '_callback2_arg%d' % len(_converted_callback_formats)
+        _converted_callback_formats[callback] = callback2, attrname
+    return _converted_callback_formats[callback]
+
+_convert_callback_formats._annspecialcase_ = 'specialize:memo'
+_converted_callback_formats = {}

Modified: pypy/branch/fast-forward/pypy/rpython/memory/gc/generation.py
==============================================================================
--- pypy/branch/fast-forward/pypy/rpython/memory/gc/generation.py	(original)
+++ pypy/branch/fast-forward/pypy/rpython/memory/gc/generation.py	Fri Nov 12 16:29:24 2010
@@ -572,16 +572,10 @@
     def _compute_current_nursery_hash(self, obj):
         return intmask(llmemory.cast_adr_to_int(obj) + self.nursery_hash_base)
 
-    def heap_stats_walk_roots(self):
-        self.last_generation_root_objects.foreach(
-            self._track_heap_ext, None)
-        self.root_walker.walk_roots(
-            SemiSpaceGC._track_heap_root,
-            SemiSpaceGC._track_heap_root,
-            SemiSpaceGC._track_heap_root)
-
-    def _track_heap_ext(self, adr, ignored):
-        self.trace(adr, self.track_heap_parent, adr)
+    def enumerate_all_roots(self, callback, arg):
+        self.last_generation_root_objects.foreach(callback, arg)
+        SemiSpaceGC.enumerate_all_roots(self, callback, arg)
+    enumerate_all_roots._annspecialcase_ = 'specialize:arg(1)'
 
     def debug_check_object(self, obj):
         """Check the invariants about 'obj' that should be true

Modified: pypy/branch/fast-forward/pypy/rpython/memory/gc/inspector.py
==============================================================================
--- pypy/branch/fast-forward/pypy/rpython/memory/gc/inspector.py	(original)
+++ pypy/branch/fast-forward/pypy/rpython/memory/gc/inspector.py	Fri Nov 12 16:29:24 2010
@@ -11,18 +11,15 @@
 
 # ---------- implementation of pypy.rlib.rgc.get_rpy_roots() ----------
 
-def _counting_rpy_root(gc, root):
+def _counting_rpy_root(obj, gc):
     gc._count_rpy += 1
 
 def _do_count_rpy_roots(gc):
     gc._count_rpy = 0
-    gc.root_walker.walk_roots(
-        _counting_rpy_root,
-        _counting_rpy_root,
-        _counting_rpy_root)
+    gc.enumerate_all_roots(_counting_rpy_root, gc)
     return gc._count_rpy
 
-def _append_rpy_root(gc, root):
+def _append_rpy_root(obj, gc):
     # Can use the gc list, but should not allocate!
     # It is essential that the list is not resizable!
     lst = gc._list_rpy
@@ -30,15 +27,12 @@
     if index >= len(lst):
         raise ValueError
     gc._count_rpy = index + 1
-    lst[index] = llmemory.cast_adr_to_ptr(root.address[0], llmemory.GCREF)
+    lst[index] = llmemory.cast_adr_to_ptr(obj, llmemory.GCREF)
 
 def _do_append_rpy_roots(gc, lst):
     gc._count_rpy = 0
     gc._list_rpy = lst
-    gc.root_walker.walk_roots(
-        _append_rpy_root,
-        _append_rpy_root,
-        _append_rpy_root)
+    gc.enumerate_all_roots(_append_rpy_root, gc)
     gc._list_rpy = None
 
 def get_rpy_roots(gc):
@@ -172,12 +166,7 @@
             self.pending.append(obj)
 
     def add_roots(self):
-        self.gc._heap_dumper = self
-        self.gc.root_walker.walk_roots(
-            _hd_add_root,
-            _hd_add_root,
-            _hd_add_root)
-        self.gc._heap_dumper = None
+        self.gc.enumerate_all_roots(_hd_add_root, self)
         pendingroots = self.pending
         self.pending = AddressStack()
         self.walk(pendingroots)
@@ -188,8 +177,8 @@
         while pending.non_empty():
             self.writeobj(pending.pop())
 
-def _hd_add_root(gc, root):
-    gc._heap_dumper.add(root.address[0])
+def _hd_add_root(obj, heap_dumper):
+    heap_dumper.add(obj)
 
 def dump_rpy_heap(gc, fd):
     heapdumper = HeapDumper(gc, fd)

Modified: pypy/branch/fast-forward/pypy/rpython/memory/gc/minimark.py
==============================================================================
--- pypy/branch/fast-forward/pypy/rpython/memory/gc/minimark.py	(original)
+++ pypy/branch/fast-forward/pypy/rpython/memory/gc/minimark.py	Fri Nov 12 16:29:24 2010
@@ -77,7 +77,7 @@
 
     # During a minor collection, the objects in the nursery that are
     # moved outside are changed in-place: their header is replaced with
-    # the value -1, and the following word is set to the address of
+    # the value -42, and the following word is set to the address of
     # where the object was moved.  This means that all objects in the
     # nursery need to be at least 2 words long, but objects outside the
     # nursery don't need to.
@@ -656,10 +656,13 @@
     def is_forwarded(self, obj):
         """Returns True if the nursery obj is marked as forwarded.
         Implemented a bit obscurely by checking an unrelated flag
-        that can never be set on a young object -- except if tid == -1.
+        that can never be set on a young object -- except if tid == -42.
         """
         assert self.is_in_nursery(obj)
-        return self.header(obj).tid & GCFLAG_FINALIZATION_ORDERING
+        result = (self.header(obj).tid & GCFLAG_FINALIZATION_ORDERING != 0)
+        if result:
+            ll_assert(self.header(obj).tid == -42, "bogus header for young obj")
+        return result
 
     def get_forwarding_address(self, obj):
         return llmemory.cast_adr_to_ptr(obj, FORWARDSTUBPTR).forw
@@ -743,6 +746,10 @@
     def JIT_max_size_of_young_obj(cls):
         return cls.TRANSLATION_PARAMS['large_object']
 
+    @classmethod
+    def JIT_minimal_size_in_nursery(cls):
+        return cls.minimal_size_in_nursery
+
     def write_barrier(self, newvalue, addr_struct):
         if self.header(addr_struct).tid & GCFLAG_NO_YOUNG_PTRS:
             self.remember_young_pointer(addr_struct, newvalue)
@@ -1080,7 +1087,7 @@
         llarena.arena_reset(obj - size_gc_header, totalsize, 0)
         llarena.arena_reserve(obj - size_gc_header,
                               size_gc_header + llmemory.sizeof(FORWARDSTUB))
-        self.header(obj).tid = -1
+        self.header(obj).tid = -42
         newobj = newhdr + size_gc_header
         llmemory.cast_adr_to_ptr(obj, FORWARDSTUBPTR).forw = newobj
         #
@@ -1281,6 +1288,11 @@
         self.run_finalizers.foreach(self._collect_obj,
                                     self.objects_to_trace)
 
+    def enumerate_all_roots(self, callback, arg):
+        self.prebuilt_root_objects.foreach(callback, arg)
+        MovingGCBase.enumerate_all_roots(self, callback, arg)
+    enumerate_all_roots._annspecialcase_ = 'specialize:arg(1)'
+
     @staticmethod
     def _collect_obj(obj, objects_to_trace):
         objects_to_trace.append(obj)

Modified: pypy/branch/fast-forward/pypy/rpython/memory/gc/semispace.py
==============================================================================
--- pypy/branch/fast-forward/pypy/rpython/memory/gc/semispace.py	(original)
+++ pypy/branch/fast-forward/pypy/rpython/memory/gc/semispace.py	Fri Nov 12 16:29:24 2010
@@ -230,6 +230,10 @@
         while self.max_space_size > size:
             self.max_space_size >>= 1
 
+    @classmethod
+    def JIT_minimal_size_in_nursery(cls):
+        return cls.object_minimal_size
+
     def collect(self, gen=0):
         self.debug_check_consistency()
         self.semispace_collect()
@@ -689,15 +693,10 @@
         self._ll_typeid_map[idx].size += llmemory.raw_malloc_usage(totsize)
         self.trace(adr, self.track_heap_parent, adr)
 
-    def _track_heap_root(self, root):
-        self.track_heap(root.address[0])
+    @staticmethod
+    def _track_heap_root(obj, self):
+        self.track_heap(obj)
 
-    def heap_stats_walk_roots(self):
-        self.root_walker.walk_roots(
-            SemiSpaceGC._track_heap_root,
-            SemiSpaceGC._track_heap_root,
-            SemiSpaceGC._track_heap_root)
-        
     def heap_stats(self):
         self._tracked_dict = self.AddressDict()
         max_tid = self.root_walker.gcdata.max_type_id
@@ -710,7 +709,7 @@
         while i < max_tid:
             self._tracked_dict.add(llmemory.cast_ptr_to_adr(ll_typeid_map[i]))
             i += 1
-        self.heap_stats_walk_roots()
+        self.enumerate_all_roots(SemiSpaceGC._track_heap_root, self)
         self._ll_typeid_map = lltype.nullptr(ARRAY_TYPEID_MAP)
         self._tracked_dict.delete()
         return ll_typeid_map

Modified: pypy/branch/fast-forward/pypy/rpython/memory/gctransform/framework.py
==============================================================================
--- pypy/branch/fast-forward/pypy/rpython/memory/gctransform/framework.py	(original)
+++ pypy/branch/fast-forward/pypy/rpython/memory/gctransform/framework.py	Fri Nov 12 16:29:24 2010
@@ -1210,7 +1210,7 @@
 sizeofaddr = llmemory.sizeof(llmemory.Address)
 
 
-class BaseRootWalker:
+class BaseRootWalker(object):
     need_root_stack = False
 
     def __init__(self, gctransformer):

Modified: pypy/branch/fast-forward/pypy/rpython/rmodel.py
==============================================================================
--- pypy/branch/fast-forward/pypy/rpython/rmodel.py	(original)
+++ pypy/branch/fast-forward/pypy/rpython/rmodel.py	Fri Nov 12 16:29:24 2010
@@ -11,14 +11,14 @@
 
 # initialization states for Repr instances 
 
-class setupstate: 
+class setupstate(object): 
     NOTINITIALIZED = 0 
     INPROGRESS = 1
     BROKEN = 2 
     FINISHED = 3
     DELAYED = 4
 
-class Repr:
+class Repr(object):
     """ An instance of Repr is associated with each instance of SomeXxx.
     It defines the chosen representation for the SomeXxx.  The Repr subclasses
     generally follows the SomeXxx subclass hierarchy, but there are numerous

Modified: pypy/branch/fast-forward/pypy/rpython/test/test_rpbc.py
==============================================================================
--- pypy/branch/fast-forward/pypy/rpython/test/test_rpbc.py	(original)
+++ pypy/branch/fast-forward/pypy/rpython/test/test_rpbc.py	Fri Nov 12 16:29:24 2010
@@ -1547,7 +1547,7 @@
     def test_always_raising_methods(self):
         class Base:
             def m(self):
-                raise NotImplementedError
+                raise KeyError
         class A(Base):
             def m(self):
                 return 42
@@ -1560,11 +1560,11 @@
                 o = B()
             try:
                 o.m()
-            except NotImplementedError:
-                pass
+            except KeyError:
+                assert 0
             return B().m()
 
-        self.interpret_raises(NotImplementedError, f, [7])
+        self.interpret_raises(KeyError, f, [7])
 
     def test_possible_missing_attribute_access(self):
         py.test.skip("Should explode or give some warning")

Modified: pypy/branch/fast-forward/pypy/translator/c/genc.py
==============================================================================
--- pypy/branch/fast-forward/pypy/translator/c/genc.py	(original)
+++ pypy/branch/fast-forward/pypy/translator/c/genc.py	Fri Nov 12 16:29:24 2010
@@ -553,7 +553,7 @@
             ('debug', '', '$(MAKE) CFLAGS="$(DEBUGFLAGS) -DRPY_ASSERT" $(TARGET)'),
             ('debug_exc', '', '$(MAKE) CFLAGS="$(DEBUGFLAGS) -DRPY_ASSERT -DDO_LOG_EXC" $(TARGET)'),
             ('debug_mem', '', '$(MAKE) CFLAGS="$(DEBUGFLAGS) -DRPY_ASSERT -DTRIVIAL_MALLOC_DEBUG" $(TARGET)'),
-            ('no_obmalloc', '', '$(MAKE) CFLAGS="-g -O1 -DRPY_ASSERT -DNO_OBMALLOC" $(TARGET)'),
+            ('no_obmalloc', '', '$(MAKE) CFLAGS="-g -O2 -DRPY_ASSERT -DNO_OBMALLOC" $(TARGET)'),
             ('linuxmemchk', '', '$(MAKE) CFLAGS="$(DEBUGFLAGS) -DRPY_ASSERT -DLINUXMEMCHK" $(TARGET)'),
             ('llsafer', '', '$(MAKE) CFLAGS="-O2 -DRPY_LL_ASSERT" $(TARGET)'),
             ('lldebug', '', '$(MAKE) CFLAGS="$(DEBUGFLAGS) -DRPY_ASSERT -DRPY_LL_ASSERT" $(TARGET)'),

Modified: pypy/branch/fast-forward/pypy/translator/c/test/test_newgc.py
==============================================================================
--- pypy/branch/fast-forward/pypy/translator/c/test/test_newgc.py	(original)
+++ pypy/branch/fast-forward/pypy/translator/c/test/test_newgc.py	Fri Nov 12 16:29:24 2010
@@ -1066,7 +1066,9 @@
 
     filename_dump = str(udir.join('test_dump_rpy_heap'))
     def define_dump_rpy_heap(self):
-        U = lltype.GcStruct('U', ('x', lltype.Signed))
+        U = lltype.GcForwardReference()
+        U.become(lltype.GcStruct('U', ('next', lltype.Ptr(U)),
+                                 ('x', lltype.Signed)))
         S = lltype.GcStruct('S', ('u', lltype.Ptr(U)))
         A = lltype.GcArray(lltype.Ptr(S))
         filename = self.filename_dump
@@ -1074,11 +1076,16 @@
         def fn():
             s = lltype.malloc(S)
             s.u = lltype.malloc(U)
+            s.u.next = lltype.malloc(U)
+            s.u.next.next = lltype.malloc(U)
             a = lltype.malloc(A, 1000)
             s2 = lltype.malloc(S)
             #
             fd = os.open(filename, os.O_WRONLY | os.O_CREAT, 0666)
             rgc.dump_rpy_heap(fd)
+            keepalive_until_here(s2)
+            keepalive_until_here(s)
+            keepalive_until_here(a)
             os.close(fd)
             return 0
 
@@ -1087,8 +1094,7 @@
     def test_dump_rpy_heap(self):
         self.run("dump_rpy_heap")
         assert os.path.exists(self.filename_dump)
-        assert os.path.getsize(self.filename_dump) > 0       # minimal test
-
+        assert os.path.getsize(self.filename_dump) > 64
 
 class TestSemiSpaceGC(TestUsingFramework, snippet.SemiSpaceGCTestDefines):
     gcpolicy = "semispace"
@@ -1173,21 +1179,22 @@
             b = 0
             c = 0
             for i in range(len(tb)):
-                if tb[i].count == 10:
+                if tb[i].count == 10:      # the type of S
                     a += 1
                     nr = i
             for i in range(len(tb)):
-                if tb[i].count == 3:
+                if tb[i].count == 3:       # the type GcArray(Ptr(S))
                     b += 1
                     c += tb[i].links[nr]
-            # we don't count b here since there can be more singletons,
+            # b can be 1 or 2 here since _heap_stats() is free to return or
+            # ignore the three GcStructs that point to the GcArray(Ptr(S)).
             # important one is c, a is for check
             return c * 100 + b * 10 + a
         return f
 
     def test_gc_heap_stats(self):
         res = self.run("gc_heap_stats")
-        assert res == 3011
+        assert res == 3011 or res == 3021
 
     def definestr_string_builder(cls):
         def fn(_):

Modified: pypy/branch/fast-forward/pypy/translator/cli/src/pypylib.cs
==============================================================================
--- pypy/branch/fast-forward/pypy/translator/cli/src/pypylib.cs	(original)
+++ pypy/branch/fast-forward/pypy/translator/cli/src/pypylib.cs	Fri Nov 12 16:29:24 2010
@@ -83,8 +83,12 @@
                 return Double.NegativeInfinity;
             else if (s == "nan")
                 return Double.NaN;
-            else
-                return System.Convert.ToDouble(s);
+            else {
+                System.Globalization.NumberFormatInfo formatter;
+                formatter = new System.Globalization.NumberFormatInfo();
+                formatter.NumberDecimalSeparator = ".";
+                return System.Convert.ToDouble(s, formatter);
+            }
         }
     }
 

Modified: pypy/branch/fast-forward/pypy/translator/goal/app_main.py
==============================================================================
--- pypy/branch/fast-forward/pypy/translator/goal/app_main.py	(original)
+++ pypy/branch/fast-forward/pypy/translator/goal/app_main.py	Fri Nov 12 16:29:24 2010
@@ -399,10 +399,6 @@
         except:
             print >> sys.stderr, "'import site' failed"
 
-    # update sys.path *after* loading site.py, in case there is a
-    # "site.py" file in the script's directory.
-    sys.path.insert(0, '')
-
     pythonwarnings = os.getenv('PYTHONWARNINGS')
     if pythonwarnings:
         warnoptions.extend(pythonwarnings.split(','))
@@ -454,6 +450,13 @@
         elif run_stdin:
             # handle the case where no command/filename/module is specified
             # on the command-line.
+
+            # update sys.path *after* loading site.py, in case there is a
+            # "site.py" file in the script's directory. Only run this if we're
+            # executing the interactive prompt, if we're running a script we
+            # put it's directory on sys.path
+            sys.path.insert(0, '')
+
             if interactive or sys.stdin.isatty():
                 # If stdin is a tty or if "-i" is specified, we print
                 # a banner and run $PYTHONSTARTUP.

Modified: pypy/branch/fast-forward/pypy/translator/goal/test2/test_app_main.py
==============================================================================
--- pypy/branch/fast-forward/pypy/translator/goal/test2/test_app_main.py	(original)
+++ pypy/branch/fast-forward/pypy/translator/goal/test2/test_app_main.py	Fri Nov 12 16:29:24 2010
@@ -95,6 +95,11 @@
         child.expect('>>> ')
         child.sendline('__name__')
         child.expect("'__main__'")
+        child.expect('>>> ')
+        child.sendline('import sys')
+        child.expect('>>> ')
+        child.sendline("'' in sys.path")
+        child.expect("True")
 
     def test_run_script(self):
         child = self.spawn([demo_script])
@@ -504,9 +509,10 @@
                 yield
             finally:
                 old_cwd.chdir()
+                # Can't call putenv with a None argument.
                 if old_pythonpath is not None:
                     os.putenv('PYTHONPATH', old_pythonpath)
-        
+
         tmpdir.join('site.py').write('print "SHOULD NOT RUN"')
         runme_py = tmpdir.join('runme.py')
         runme_py.write('print "some text"')
@@ -527,9 +533,9 @@
 
         with chdir_and_unset_pythonpath(tmpdir):
             data = self.run(cmdline2, python_flags='-S')
-
         assert data.startswith("some new text\n")
         assert repr(str(tmpdir.join('otherpath'))) in data
+        assert "''" not in data
 
 
 class AppTestAppMain:



More information about the Pypy-commit mailing list