[pypy-svn] r78902 - in pypy/branch/fast-forward: lib-python lib-python/modified-2.5.2/test lib_pypy/ctypes_config_cache lib_pypy/ctypes_config_cache/test lib_pypy/pypy_test pypy/annotation pypy/config pypy/config/test pypy/doc pypy/doc/config pypy/interpreter pypy/interpreter/test pypy/jit/backend pypy/jit/backend/llgraph pypy/jit/backend/llsupport/test pypy/jit/backend/x86 pypy/jit/backend/x86/test pypy/jit/backend/x86/tool pypy/jit/codewriter pypy/jit/codewriter/test pypy/jit/metainterp pypy/jit/metainterp/optimizeopt pypy/jit/metainterp/test pypy/jit/tl pypy/jit/tool pypy/jit/tool/test pypy/module/__builtin__ pypy/module/__builtin__/test pypy/module/__pypy__ pypy/module/__pypy__/test pypy/module/_bisect pypy/module/_bisect/test pypy/module/gc pypy/module/gc/test pypy/module/pypyjit pypy/module/pypyjit/test pypy/module/signal pypy/module/signal/test pypy/module/sys pypy/module/thread pypy/module/thread/test pypy/objspace pypy/objspace/std pypy/objspace/std/test pypy/rlib pypy/rlib/test pypy/rpython/lltypesystem pypy/rpython/memory/gc pypy/rpython/test pypy/tool pypy/translator/c pypy/translator/c/gcc pypy/translator/c/gcc/test pypy/translator/c/gcc/test/darwin64 pypy/translator/c/src

afa at codespeak.net afa at codespeak.net
Tue Nov 9 00:03:09 CET 2010


Author: afa
Date: Tue Nov  9 00:03:02 2010
New Revision: 78902

Added:
   pypy/branch/fast-forward/lib-python/modified-2.5.2/test/test_dict.py
      - copied unchanged from r78900, pypy/trunk/lib-python/modified-2.5.2/test/test_dict.py
   pypy/branch/fast-forward/lib_pypy/ctypes_config_cache/dumpcache.py
      - copied unchanged from r78900, pypy/trunk/lib_pypy/ctypes_config_cache/dumpcache.py
   pypy/branch/fast-forward/pypy/doc/config/objspace.usemodules._bisect.txt
      - copied unchanged from r78900, pypy/trunk/pypy/doc/config/objspace.usemodules._bisect.txt
   pypy/branch/fast-forward/pypy/jit/codewriter/test/test_void_list.py
      - copied unchanged from r78900, pypy/trunk/pypy/jit/codewriter/test/test_void_list.py
   pypy/branch/fast-forward/pypy/module/_bisect/   (props changed)
      - copied from r78900, pypy/trunk/pypy/module/_bisect/
   pypy/branch/fast-forward/pypy/module/_bisect/__init__.py
      - copied unchanged from r78900, pypy/trunk/pypy/module/_bisect/__init__.py
   pypy/branch/fast-forward/pypy/module/_bisect/app_bisect.py
      - copied unchanged from r78900, pypy/trunk/pypy/module/_bisect/app_bisect.py
   pypy/branch/fast-forward/pypy/module/_bisect/interp_bisect.py
      - copied unchanged from r78900, pypy/trunk/pypy/module/_bisect/interp_bisect.py
   pypy/branch/fast-forward/pypy/module/_bisect/test/   (props changed)
      - copied from r78900, pypy/trunk/pypy/module/_bisect/test/
   pypy/branch/fast-forward/pypy/module/_bisect/test/__init__.py
      - copied unchanged from r78900, pypy/trunk/pypy/module/_bisect/test/__init__.py
   pypy/branch/fast-forward/pypy/module/_bisect/test/test_bisect.py
      - copied unchanged from r78900, pypy/trunk/pypy/module/_bisect/test/test_bisect.py
   pypy/branch/fast-forward/pypy/objspace/std/test/test_methodcache.py
      - copied unchanged from r78900, pypy/trunk/pypy/objspace/std/test/test_methodcache.py
   pypy/branch/fast-forward/pypy/translator/c/gcc/test/darwin64/
      - copied from r78900, pypy/trunk/pypy/translator/c/gcc/test/darwin64/
   pypy/branch/fast-forward/pypy/translator/c/gcc/test/darwin64/track0.s
      - copied unchanged from r78900, pypy/trunk/pypy/translator/c/gcc/test/darwin64/track0.s
   pypy/branch/fast-forward/pypy/translator/c/gcc/test/darwin64/track1.s
      - copied unchanged from r78900, pypy/trunk/pypy/translator/c/gcc/test/darwin64/track1.s
Removed:
   pypy/branch/fast-forward/pypy/doc/config/objspace.std.withinlineddict.txt
   pypy/branch/fast-forward/pypy/doc/config/objspace.std.withshadowtracking.txt
   pypy/branch/fast-forward/pypy/doc/config/objspace.std.withsharingdict.txt
   pypy/branch/fast-forward/pypy/objspace/std/inlinedict.py
   pypy/branch/fast-forward/pypy/objspace/std/sharingdict.py
   pypy/branch/fast-forward/pypy/objspace/std/test/test_inlinedict.py
   pypy/branch/fast-forward/pypy/objspace/std/test/test_shadowtracking.py
   pypy/branch/fast-forward/pypy/objspace/std/test/test_sharingdict.py
Modified:
   pypy/branch/fast-forward/lib-python/conftest.py
   pypy/branch/fast-forward/lib-python/modified-2.5.2/test/mapping_tests.py
   pypy/branch/fast-forward/lib-python/modified-2.5.2/test/test_descr.py
   pypy/branch/fast-forward/lib_pypy/ctypes_config_cache/   (props changed)
   pypy/branch/fast-forward/lib_pypy/ctypes_config_cache/locale.ctc.py
   pypy/branch/fast-forward/lib_pypy/ctypes_config_cache/pyexpat.ctc.py
   pypy/branch/fast-forward/lib_pypy/ctypes_config_cache/rebuild.py
   pypy/branch/fast-forward/lib_pypy/ctypes_config_cache/resource.ctc.py
   pypy/branch/fast-forward/lib_pypy/ctypes_config_cache/syslog.ctc.py
   pypy/branch/fast-forward/lib_pypy/ctypes_config_cache/test/test_cache.py
   pypy/branch/fast-forward/lib_pypy/pypy_test/test_ctypes_support.py
   pypy/branch/fast-forward/pypy/annotation/bookkeeper.py
   pypy/branch/fast-forward/pypy/annotation/classdef.py
   pypy/branch/fast-forward/pypy/annotation/description.py
   pypy/branch/fast-forward/pypy/annotation/dictdef.py
   pypy/branch/fast-forward/pypy/annotation/listdef.py
   pypy/branch/fast-forward/pypy/annotation/specialize.py
   pypy/branch/fast-forward/pypy/annotation/unaryop.py
   pypy/branch/fast-forward/pypy/config/pypyoption.py
   pypy/branch/fast-forward/pypy/config/test/test_pypyoption.py
   pypy/branch/fast-forward/pypy/doc/config/objspace.opcodes.CALL_METHOD.txt
   pypy/branch/fast-forward/pypy/doc/getting-started.txt
   pypy/branch/fast-forward/pypy/doc/interpreter-optimizations.txt
   pypy/branch/fast-forward/pypy/interpreter/baseobjspace.py
   pypy/branch/fast-forward/pypy/interpreter/executioncontext.py
   pypy/branch/fast-forward/pypy/interpreter/gateway.py
   pypy/branch/fast-forward/pypy/interpreter/pyopcode.py
   pypy/branch/fast-forward/pypy/interpreter/test/test_executioncontext.py
   pypy/branch/fast-forward/pypy/interpreter/typedef.py
   pypy/branch/fast-forward/pypy/jit/backend/detect_cpu.py
   pypy/branch/fast-forward/pypy/jit/backend/llgraph/llimpl.py
   pypy/branch/fast-forward/pypy/jit/backend/llgraph/runner.py
   pypy/branch/fast-forward/pypy/jit/backend/llsupport/test/test_gc.py
   pypy/branch/fast-forward/pypy/jit/backend/model.py
   pypy/branch/fast-forward/pypy/jit/backend/x86/assembler.py
   pypy/branch/fast-forward/pypy/jit/backend/x86/runner.py
   pypy/branch/fast-forward/pypy/jit/backend/x86/test/test_runner.py
   pypy/branch/fast-forward/pypy/jit/backend/x86/tool/viewcode.py
   pypy/branch/fast-forward/pypy/jit/codewriter/call.py
   pypy/branch/fast-forward/pypy/jit/codewriter/format.py
   pypy/branch/fast-forward/pypy/jit/codewriter/jtransform.py
   pypy/branch/fast-forward/pypy/jit/codewriter/test/test_list.py
   pypy/branch/fast-forward/pypy/jit/metainterp/blackhole.py
   pypy/branch/fast-forward/pypy/jit/metainterp/compile.py
   pypy/branch/fast-forward/pypy/jit/metainterp/logger.py
   pypy/branch/fast-forward/pypy/jit/metainterp/optimizeopt/rewrite.py
   pypy/branch/fast-forward/pypy/jit/metainterp/pyjitpl.py
   pypy/branch/fast-forward/pypy/jit/metainterp/resoperation.py
   pypy/branch/fast-forward/pypy/jit/metainterp/test/test_basic.py
   pypy/branch/fast-forward/pypy/jit/metainterp/test/test_logger.py
   pypy/branch/fast-forward/pypy/jit/metainterp/test/test_oparser.py
   pypy/branch/fast-forward/pypy/jit/metainterp/test/test_optimizeopt.py
   pypy/branch/fast-forward/pypy/jit/tl/pypyjit.py
   pypy/branch/fast-forward/pypy/jit/tool/oparser.py
   pypy/branch/fast-forward/pypy/jit/tool/pypytrace.vim
   pypy/branch/fast-forward/pypy/jit/tool/showstats.py
   pypy/branch/fast-forward/pypy/jit/tool/test/test_traceviewer.py
   pypy/branch/fast-forward/pypy/module/__builtin__/descriptor.py
   pypy/branch/fast-forward/pypy/module/__builtin__/interp_classobj.py
   pypy/branch/fast-forward/pypy/module/__builtin__/test/test_classobj.py
   pypy/branch/fast-forward/pypy/module/__pypy__/__init__.py
   pypy/branch/fast-forward/pypy/module/__pypy__/test/test_special.py
   pypy/branch/fast-forward/pypy/module/gc/interp_gc.py
   pypy/branch/fast-forward/pypy/module/gc/test/test_gc.py
   pypy/branch/fast-forward/pypy/module/pypyjit/interp_jit.py
   pypy/branch/fast-forward/pypy/module/pypyjit/policy.py
   pypy/branch/fast-forward/pypy/module/pypyjit/test/test_policy.py
   pypy/branch/fast-forward/pypy/module/pypyjit/test/test_pypy_c.py
   pypy/branch/fast-forward/pypy/module/signal/__init__.py
   pypy/branch/fast-forward/pypy/module/signal/interp_signal.py
   pypy/branch/fast-forward/pypy/module/signal/test/test_signal.py
   pypy/branch/fast-forward/pypy/module/sys/__init__.py
   pypy/branch/fast-forward/pypy/module/sys/version.py
   pypy/branch/fast-forward/pypy/module/sys/vm.py
   pypy/branch/fast-forward/pypy/module/thread/gil.py
   pypy/branch/fast-forward/pypy/module/thread/test/test_gil.py
   pypy/branch/fast-forward/pypy/objspace/descroperation.py
   pypy/branch/fast-forward/pypy/objspace/std/callmethod.py
   pypy/branch/fast-forward/pypy/objspace/std/celldict.py
   pypy/branch/fast-forward/pypy/objspace/std/dictmultiobject.py
   pypy/branch/fast-forward/pypy/objspace/std/inttype.py
   pypy/branch/fast-forward/pypy/objspace/std/listobject.py
   pypy/branch/fast-forward/pypy/objspace/std/longtype.py
   pypy/branch/fast-forward/pypy/objspace/std/mapdict.py
   pypy/branch/fast-forward/pypy/objspace/std/objspace.py
   pypy/branch/fast-forward/pypy/objspace/std/proxyobject.py
   pypy/branch/fast-forward/pypy/objspace/std/smallintobject.py
   pypy/branch/fast-forward/pypy/objspace/std/stringobject.py
   pypy/branch/fast-forward/pypy/objspace/std/strutil.py
   pypy/branch/fast-forward/pypy/objspace/std/test/test_dictmultiobject.py
   pypy/branch/fast-forward/pypy/objspace/std/test/test_longobject.py
   pypy/branch/fast-forward/pypy/objspace/std/test/test_mapdict.py
   pypy/branch/fast-forward/pypy/objspace/std/test/test_strutil.py
   pypy/branch/fast-forward/pypy/objspace/std/typeobject.py
   pypy/branch/fast-forward/pypy/rlib/jit.py
   pypy/branch/fast-forward/pypy/rlib/objectmodel.py
   pypy/branch/fast-forward/pypy/rlib/rbigint.py
   pypy/branch/fast-forward/pypy/rlib/test/test_rbigint.py
   pypy/branch/fast-forward/pypy/rpython/lltypesystem/rdict.py
   pypy/branch/fast-forward/pypy/rpython/memory/gc/minimark.py
   pypy/branch/fast-forward/pypy/rpython/test/test_rdict.py
   pypy/branch/fast-forward/pypy/tool/alarm.py
   pypy/branch/fast-forward/pypy/tool/readdictinfo.py
   pypy/branch/fast-forward/pypy/tool/rundictbenchmarks.py
   pypy/branch/fast-forward/pypy/tool/statistic_irc_log.py
   pypy/branch/fast-forward/pypy/tool/watchdog.py
   pypy/branch/fast-forward/pypy/tool/watchdog_nt.py
   pypy/branch/fast-forward/pypy/translator/c/gcc/test/test_trackgcroot.py
   pypy/branch/fast-forward/pypy/translator/c/gcc/trackgcroot.py
   pypy/branch/fast-forward/pypy/translator/c/genc.py
   pypy/branch/fast-forward/pypy/translator/c/src/g_include.h
   pypy/branch/fast-forward/pypy/translator/c/src/int.h
   pypy/branch/fast-forward/pypy/translator/c/src/signals.h
Log:
merge from trunk:
svn merge -r78316:78900 ../trunk


Modified: pypy/branch/fast-forward/lib-python/conftest.py
==============================================================================
--- pypy/branch/fast-forward/lib-python/conftest.py	(original)
+++ pypy/branch/fast-forward/lib-python/conftest.py	Tue Nov  9 00:03:02 2010
@@ -131,7 +131,7 @@
     RegrTest('test_binhex.py'),
 
     RegrTest('test_binop.py', core=True),
-    RegrTest('test_bisect.py', core=True),
+    RegrTest('test_bisect.py', core=True, usemodules='_bisect'),
     RegrTest('test_bool.py', core=True),
     RegrTest('test_bsddb.py', skip="unsupported extension module"),
     RegrTest('test_bsddb185.py', skip="unsupported extension module"),

Modified: pypy/branch/fast-forward/lib-python/modified-2.5.2/test/mapping_tests.py
==============================================================================
--- pypy/branch/fast-forward/lib-python/modified-2.5.2/test/mapping_tests.py	(original)
+++ pypy/branch/fast-forward/lib-python/modified-2.5.2/test/mapping_tests.py	Tue Nov  9 00:03:02 2010
@@ -1,6 +1,7 @@
 # tests common to dict and UserDict
 import unittest
 import UserDict
+from test import test_support
 
 
 class BasicTestMappingProtocol(unittest.TestCase):
@@ -525,7 +526,8 @@
                     self.assertEqual(va, int(ka))
                     kb, vb = tb = b.popitem()
                     self.assertEqual(vb, int(kb))
-                    self.assert_(not(copymode < 0 and ta != tb))
+                    if test_support.check_impl_detail():
+                        self.assert_(not(copymode < 0 and ta != tb))
                 self.assert_(not a)
                 self.assert_(not b)
 

Modified: pypy/branch/fast-forward/lib-python/modified-2.5.2/test/test_descr.py
==============================================================================
--- pypy/branch/fast-forward/lib-python/modified-2.5.2/test/test_descr.py	(original)
+++ pypy/branch/fast-forward/lib-python/modified-2.5.2/test/test_descr.py	Tue Nov  9 00:03:02 2010
@@ -2028,7 +2028,9 @@
     except TypeError, msg:
         verify(str(msg).find("weak reference") >= 0)
     else:
-        verify(0, "weakref.ref(no) should be illegal")
+        # in PyPy it is (sometimes) possible to take a weakref here
+        #verify(0, "weakref.ref(no) should be illegal")
+        pass
     class Weak(object):
         __slots__ = ['foo', '__weakref__']
     yes = Weak()

Modified: pypy/branch/fast-forward/lib_pypy/ctypes_config_cache/locale.ctc.py
==============================================================================
--- pypy/branch/fast-forward/lib_pypy/ctypes_config_cache/locale.ctc.py	(original)
+++ pypy/branch/fast-forward/lib_pypy/ctypes_config_cache/locale.ctc.py	Tue Nov  9 00:03:02 2010
@@ -5,7 +5,7 @@
 
 from ctypes_configure.configure import (configure, ExternalCompilationInfo,
     ConstantInteger, DefinedConstantInteger, SimpleType, check_eci)
-from ctypes_configure.dumpcache import dumpcache
+import dumpcache
 
 # ____________________________________________________________
 
@@ -70,4 +70,4 @@
 
 config['ALL_CONSTANTS'] = tuple(_CONSTANTS)
 config['HAS_LANGINFO'] = HAS_LANGINFO
-dumpcache(__file__, '_locale_cache.py', config)
+dumpcache.dumpcache2('locale', config)

Modified: pypy/branch/fast-forward/lib_pypy/ctypes_config_cache/pyexpat.ctc.py
==============================================================================
--- pypy/branch/fast-forward/lib_pypy/ctypes_config_cache/pyexpat.ctc.py	(original)
+++ pypy/branch/fast-forward/lib_pypy/ctypes_config_cache/pyexpat.ctc.py	Tue Nov  9 00:03:02 2010
@@ -5,7 +5,8 @@
 
 import ctypes
 from ctypes import c_char_p, c_int, c_void_p, c_char
-from ctypes_configure import configure, dumpcache
+from ctypes_configure import configure
+import dumpcache
 
 
 class CConfigure:
@@ -41,4 +42,4 @@
 
 config = configure.configure(CConfigure)
 
-dumpcache.dumpcache(__file__, '_pyexpat_cache.py', config)
+dumpcache.dumpcache2('pyexpat', config)

Modified: pypy/branch/fast-forward/lib_pypy/ctypes_config_cache/rebuild.py
==============================================================================
--- pypy/branch/fast-forward/lib_pypy/ctypes_config_cache/rebuild.py	(original)
+++ pypy/branch/fast-forward/lib_pypy/ctypes_config_cache/rebuild.py	Tue Nov  9 00:03:02 2010
@@ -31,10 +31,25 @@
         sys.path[:] = path
 
 def try_rebuild():
+    from pypy.jit.backend import detect_cpu
+    model = detect_cpu.autodetect_main_model_and_size()
+    # remove the files '_*_model_.py'
+    left = {}
+    for p in os.listdir(_dirpath):
+        if p.startswith('_') and (p.endswith('_%s_.py' % model) or
+                                  p.endswith('_%s_.pyc' % model)):
+            os.unlink(os.path.join(_dirpath, p))
+        elif p.startswith('_') and (p.endswith('_.py') or
+                                    p.endswith('_.pyc')):
+            for i in range(2, len(p)-4):
+                left[p[:i]] = True
+    # remove the files '_*_cache.py' if there is no '_*_*_.py' left around
     for p in os.listdir(_dirpath):
         if p.startswith('_') and (p.endswith('_cache.py') or
                                   p.endswith('_cache.pyc')):
-            os.unlink(os.path.join(_dirpath, p))
+            if p[:-9] not in left:
+                os.unlink(os.path.join(_dirpath, p))
+    #
     for p in os.listdir(_dirpath):
         if p.endswith('.ctc.py'):
             try:

Modified: pypy/branch/fast-forward/lib_pypy/ctypes_config_cache/resource.ctc.py
==============================================================================
--- pypy/branch/fast-forward/lib_pypy/ctypes_config_cache/resource.ctc.py	(original)
+++ pypy/branch/fast-forward/lib_pypy/ctypes_config_cache/resource.ctc.py	Tue Nov  9 00:03:02 2010
@@ -5,7 +5,7 @@
 
 
 from ctypes import sizeof
-from ctypes_configure.dumpcache import dumpcache
+import dumpcache
 from ctypes_configure.configure import (configure,
     ExternalCompilationInfo, ConstantInteger, DefinedConstantInteger,
     SimpleType)
@@ -59,4 +59,4 @@
         del config[key]
 
 config['ALL_CONSTANTS'] = _CONSTANTS + tuple(optional_constants)
-dumpcache(__file__, '_resource_cache.py', config)
+dumpcache.dumpcache2('resource', config)

Modified: pypy/branch/fast-forward/lib_pypy/ctypes_config_cache/syslog.ctc.py
==============================================================================
--- pypy/branch/fast-forward/lib_pypy/ctypes_config_cache/syslog.ctc.py	(original)
+++ pypy/branch/fast-forward/lib_pypy/ctypes_config_cache/syslog.ctc.py	Tue Nov  9 00:03:02 2010
@@ -5,7 +5,7 @@
 
 from ctypes_configure.configure import (configure,
     ExternalCompilationInfo, ConstantInteger, DefinedConstantInteger)
-from ctypes_configure.dumpcache import dumpcache
+import dumpcache
 
 
 _CONSTANTS = (
@@ -72,4 +72,4 @@
 all_constants = config.keys()
 all_constants.sort()
 config['ALL_CONSTANTS'] = tuple(all_constants)
-dumpcache(__file__, '_syslog_cache.py', config)
+dumpcache.dumpcache2('syslog', config)

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	Tue Nov  9 00:03:02 2010
@@ -7,19 +7,27 @@
 
 def run(filename, outputname):
     filepath = dirpath.join(filename)
-    tmpdir = udir.ensure('testcache-' + filename, dir=True)
-    outputpath = tmpdir.join(outputname)
-    d = {'__file__': str(outputpath)}
+    tmpdir2 = udir.ensure('testcache-' + filename, dir=True)
+    tmpdir = tmpdir2.ensure('ctypes_config_cache', dir=True)
+    tmpdir.join('__init__.py').write('\n')
+    tmpdir.join('dumpcache.py').write(dirpath.join('dumpcache.py').read())
     path = sys.path[:]
     try:
-        sys.path.insert(0, str(dirpath))
-        execfile(str(filepath), d)
+        sys.path.insert(0, str(tmpdir))
+        execfile(str(filepath), {})
     finally:
         sys.path[:] = path
+        sys.modules.pop('dumpcache', None)
     #
+    outputpath = tmpdir.join(outputname)
     assert outputpath.check(exists=1)
     d = {}
-    execfile(str(outputpath), d)
+    try:
+        sys.path.insert(0, str(tmpdir2))
+        execfile(str(outputpath), d)
+    finally:
+        sys.path[:] = path
+        sys.modules.pop('ctypes_config_cache', None)
     return d
 
 

Modified: pypy/branch/fast-forward/lib_pypy/pypy_test/test_ctypes_support.py
==============================================================================
--- pypy/branch/fast-forward/lib_pypy/pypy_test/test_ctypes_support.py	(original)
+++ pypy/branch/fast-forward/lib_pypy/pypy_test/test_ctypes_support.py	Tue Nov  9 00:03:02 2010
@@ -22,12 +22,11 @@
     assert get_errno() == 0
 
 def test_argument_conversion_and_checks():
-    import ctypes
-    libc = ctypes.cdll.LoadLibrary("libc.so.6")
-    libc.strlen.argtypes = ctypes.c_char_p,
-    libc.strlen.restype = ctypes.c_size_t
-    assert libc.strlen("eggs") == 4
-    
+    strlen = standard_c_lib.strlen
+    strlen.argtypes = [c_char_p]
+    strlen.restype = c_size_t
+    assert strlen("eggs") == 4
+
     # Should raise ArgumentError, not segfault
-    py.test.raises(ctypes.ArgumentError, libc.strlen, False)
+    py.test.raises(ArgumentError, strlen, False)
 

Modified: pypy/branch/fast-forward/pypy/annotation/bookkeeper.py
==============================================================================
--- pypy/branch/fast-forward/pypy/annotation/bookkeeper.py	(original)
+++ pypy/branch/fast-forward/pypy/annotation/bookkeeper.py	Tue Nov  9 00:03:02 2010
@@ -24,7 +24,7 @@
 from pypy.rpython import extregistry
 from pypy.tool.identity_dict import identity_dict
 
-class Stats:
+class Stats(object):
 
     def __init__(self, bookkeeper):
         self.bookkeeper = bookkeeper
@@ -137,7 +137,7 @@
     def consider_dict_delitem(self, dic):
         return dic
 
-class Bookkeeper:
+class Bookkeeper(object):
     """The log of choices that have been made while analysing the operations.
     It ensures that the same 'choice objects' will be returned if we ask
     again during reflowing.  Like ExecutionContext, there is an implicit
@@ -736,7 +736,7 @@
         return True
 
 # for parsing call arguments
-class RPythonCallsSpace:
+class RPythonCallsSpace(object):
     """Pseudo Object Space providing almost no real operation.
     For the Arguments class: if it really needs other operations, it means
     that the call pattern is too complex for R-Python.

Modified: pypy/branch/fast-forward/pypy/annotation/classdef.py
==============================================================================
--- pypy/branch/fast-forward/pypy/annotation/classdef.py	(original)
+++ pypy/branch/fast-forward/pypy/annotation/classdef.py	Tue Nov  9 00:03:02 2010
@@ -58,7 +58,7 @@
 #        same name in all subclasses of A, if any.  (Parent class attributes can
 #        be visible in reads from instances of subclasses.)
 
-class Attribute:
+class Attribute(object):
     # readonly-ness
     # SomeThing-ness
     # NB.  an attribute is readonly if it is a constant class attribute.
@@ -402,7 +402,7 @@
 
 # ____________________________________________________________
 
-class InstanceSource:
+class InstanceSource(object):
     instance_level = True
 
     def __init__(self, bookkeeper, obj):

Modified: pypy/branch/fast-forward/pypy/annotation/description.py
==============================================================================
--- pypy/branch/fast-forward/pypy/annotation/description.py	(original)
+++ pypy/branch/fast-forward/pypy/annotation/description.py	Tue Nov  9 00:03:02 2010
@@ -6,7 +6,7 @@
 from pypy.tool.sourcetools import valid_identifier
 from pypy.tool.pairtype import extendabletype
 
-class CallFamily:
+class CallFamily(object):
     """A family of Desc objects that could be called from common call sites.
     The call families are conceptually a partition of all (callable) Desc
     objects, where the equivalence relation is the transitive closure of
@@ -51,7 +51,7 @@
             self.total_calltable_size += 1
 
 
-class FrozenAttrFamily:
+class FrozenAttrFamily(object):
     """A family of FrozenDesc objects that have any common 'getattr' sites.
     The attr families are conceptually a partition of FrozenDesc objects,
     where the equivalence relation is the transitive closure of:
@@ -80,7 +80,7 @@
         self.attrs[attrname] = s_value
 
 
-class ClassAttrFamily:
+class ClassAttrFamily(object):
     """A family of ClassDesc objects that have common 'getattr' sites for a
     given attribute name.  The attr families are conceptually a partition
     of ClassDesc objects, where the equivalence relation is the transitive

Modified: pypy/branch/fast-forward/pypy/annotation/dictdef.py
==============================================================================
--- pypy/branch/fast-forward/pypy/annotation/dictdef.py	(original)
+++ pypy/branch/fast-forward/pypy/annotation/dictdef.py	Tue Nov  9 00:03:02 2010
@@ -77,7 +77,7 @@
             dictdef.dictvalue = self
 
 
-class DictDef:
+class DictDef(object):
     """A dict definition remembers how general the keys and values in that
     particular dict have to be.  Every dict creation makes a new DictDef,
     and the union of two dicts merges the DictKeys and DictValues that each

Modified: pypy/branch/fast-forward/pypy/annotation/listdef.py
==============================================================================
--- pypy/branch/fast-forward/pypy/annotation/listdef.py	(original)
+++ pypy/branch/fast-forward/pypy/annotation/listdef.py	Tue Nov  9 00:03:02 2010
@@ -6,7 +6,7 @@
 class TooLateForChange(Exception):
     pass
 
-class ListItem:
+class ListItem(object):
     mutated = False    # True for lists mutated after creation
     resized = False    # True for lists resized after creation
     range_step = None  # the step -- only for lists only created by a range()
@@ -117,7 +117,7 @@
         return updated
 
 
-class ListDef:
+class ListDef(object):
     """A list definition remembers how general the items in that particular
     list have to be.  Every list creation makes a new ListDef, and the union
     of two lists merges the ListItems that each ListDef stores."""

Modified: pypy/branch/fast-forward/pypy/annotation/specialize.py
==============================================================================
--- pypy/branch/fast-forward/pypy/annotation/specialize.py	(original)
+++ pypy/branch/fast-forward/pypy/annotation/specialize.py	Tue Nov  9 00:03:02 2010
@@ -100,7 +100,7 @@
 # ____________________________________________________________________________
 # specializations
 
-class MemoTable:
+class MemoTable(object):
     def __init__(self, funcdesc, args, value):
         self.funcdesc = funcdesc
         self.table = {args: value}

Modified: pypy/branch/fast-forward/pypy/annotation/unaryop.py
==============================================================================
--- pypy/branch/fast-forward/pypy/annotation/unaryop.py	(original)
+++ pypy/branch/fast-forward/pypy/annotation/unaryop.py	Tue Nov  9 00:03:02 2010
@@ -434,6 +434,9 @@
     def method_clear(dct):
         pass
 
+    def method_popitem(dct):
+        return dct.getanyitem('items')
+
     def _can_only_throw(dic, *ignore):
         if dic1.dictdef.dictkey.custom_eq_hash:
             return None    # r_dict: can throw anything

Modified: pypy/branch/fast-forward/pypy/config/pypyoption.py
==============================================================================
--- pypy/branch/fast-forward/pypy/config/pypyoption.py	(original)
+++ pypy/branch/fast-forward/pypy/config/pypyoption.py	Tue Nov  9 00:03:02 2010
@@ -27,11 +27,11 @@
 working_modules = default_modules.copy()
 working_modules.update(dict.fromkeys(
     ["_socket", "unicodedata", "mmap", "fcntl",
-      "rctime" , "select", "zipimport", "_lsprof",
+     "rctime" , "select", "zipimport", "_lsprof",
      "crypt", "signal", "_rawffi", "termios", "zlib", "bz2",
      "struct", "_hashlib", "_md5", "_sha", "_minimal_curses", "cStringIO",
      "thread", "itertools", "pyexpat", "_ssl", "cpyext", "array",
-     "_multiprocessing", '_warnings']
+     "_bisect", "_multiprocessing", '_warnings']
 ))
 
 working_oo_modules = default_modules.copy()
@@ -232,27 +232,15 @@
                    requires=[("objspace.opcodes.CALL_LIKELY_BUILTIN", False),
                              ("objspace.honor__builtins__", False)]),
 
-        BoolOption("withsharingdict",
-                   "use dictionaries that share the keys part",
-                   default=False),
-
         BoolOption("withdictmeasurement",
                    "create huge files with masses of information "
                    "about dictionaries",
                    default=False),
 
-        BoolOption("withinlineddict",
-                   "make instances more compact by revoming a level of indirection",
-                   default=False,
-                   requires=[("objspace.std.withshadowtracking", False)]),
-
         BoolOption("withmapdict",
                    "make instances really small but slow without the JIT",
                    default=False,
-                   requires=[("objspace.std.withshadowtracking", False),
-                             ("objspace.std.withinlineddict", False),
-                             ("objspace.std.withsharingdict", False),
-                             ("objspace.std.getattributeshortcut", True),
+                   requires=[("objspace.std.getattributeshortcut", True),
                              ("objspace.std.withtypeversion", True),
                        ]),
 
@@ -269,12 +257,6 @@
                    # weakrefs needed, because of get_subclasses()
                    requires=[("translation.rweakref", True)]),
 
-        BoolOption("withshadowtracking",
-                   "track whether an instance attribute shadows a type"
-                   " attribute",
-                   default=False,
-                   requires=[("objspace.std.withtypeversion", True),
-                             ("translation.rweakref", True)]),
         BoolOption("withmethodcache",
                    "try to cache method lookups",
                    default=False,
@@ -346,9 +328,6 @@
         config.objspace.std.suggest(optimized_list_getitem=True)
         config.objspace.std.suggest(getattributeshortcut=True)
         config.objspace.std.suggest(newshortcut=True)        
-        if type_system != 'ootype':
-            config.objspace.std.suggest(withsharingdict=True)
-        config.objspace.std.suggest(withinlineddict=True)
 
     # extra costly optimizations only go in level 3
     if level == '3':
@@ -377,7 +356,7 @@
     # extra optimizations with the JIT
     if level == 'jit':
         config.objspace.std.suggest(withcelldict=True)
-        #config.objspace.std.suggest(withmapdict=True)
+        config.objspace.std.suggest(withmapdict=True)
 
 
 def enable_allworkingmodules(config):

Modified: pypy/branch/fast-forward/pypy/config/test/test_pypyoption.py
==============================================================================
--- pypy/branch/fast-forward/pypy/config/test/test_pypyoption.py	(original)
+++ pypy/branch/fast-forward/pypy/config/test/test_pypyoption.py	Tue Nov  9 00:03:02 2010
@@ -47,7 +47,7 @@
 def test_set_pypy_opt_level():
     conf = get_pypy_config()
     set_pypy_opt_level(conf, '2')
-    assert conf.objspace.std.withsharingdict
+    assert conf.objspace.std.newshortcut
     conf = get_pypy_config()
     set_pypy_opt_level(conf, '0')
     assert not conf.objspace.std.newshortcut
@@ -59,7 +59,6 @@
 
     assert not conf.objspace.std.withtypeversion
     assert not conf.objspace.std.withmethodcache
-    assert not conf.objspace.std.withshadowtracking
 
 def test_check_documentation():
     def check_file_exists(fn):

Modified: pypy/branch/fast-forward/pypy/doc/config/objspace.opcodes.CALL_METHOD.txt
==============================================================================
--- pypy/branch/fast-forward/pypy/doc/config/objspace.opcodes.CALL_METHOD.txt	(original)
+++ pypy/branch/fast-forward/pypy/doc/config/objspace.opcodes.CALL_METHOD.txt	Tue Nov  9 00:03:02 2010
@@ -5,8 +5,6 @@
 case.  So far, this only works for calls with no keyword, no ``*arg``
 and no ``**arg`` but it would be easy to extend.
 
-Gives the best results combined with :config:`objspace.std.withshadowtracking`.
-
 For more information, see the section in `Standard Interpreter Optimizations`_.
 
 .. _`Standard Interpreter Optimizations`: ../interpreter-optimizations.html#lookup-method-call-method

Modified: pypy/branch/fast-forward/pypy/doc/getting-started.txt
==============================================================================
--- pypy/branch/fast-forward/pypy/doc/getting-started.txt	(original)
+++ pypy/branch/fast-forward/pypy/doc/getting-started.txt	Tue Nov  9 00:03:02 2010
@@ -18,6 +18,7 @@
 translation process - as opposed to encoding low level details into the
 language implementation itself. `more...`_
 
+
 .. _Python: http://docs.python.org/ref
 .. _`more...`: architecture.html
 

Modified: pypy/branch/fast-forward/pypy/doc/interpreter-optimizations.txt
==============================================================================
--- pypy/branch/fast-forward/pypy/doc/interpreter-optimizations.txt	(original)
+++ pypy/branch/fast-forward/pypy/doc/interpreter-optimizations.txt	Tue Nov  9 00:03:02 2010
@@ -153,8 +153,8 @@
 dicts:
 the representation of the instance dict contains only a list of values.
 
-You can enable this feature with the :config:`objspace.std.withsharingdict`
-option.
+A more advanced version of sharing dicts, called *map dicts,* is available
+with the :config:`objspace.std.withmapdict` option.
 
 Builtin-Shadowing
 +++++++++++++++++
@@ -219,8 +219,7 @@
 shadowing the class attribute. If we know that there is no shadowing (since
 instance dict tells us that) we can save this lookup on the instance dictionary.
 
-You can enable this feature with the :config:`objspace.std.withshadowtracking`
-option.
+*This was deprecated and is no longer available.*
 
 
 Method Caching

Modified: pypy/branch/fast-forward/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/branch/fast-forward/pypy/interpreter/baseobjspace.py	(original)
+++ pypy/branch/fast-forward/pypy/interpreter/baseobjspace.py	Tue Nov  9 00:03:02 2010
@@ -36,13 +36,10 @@
             return space.finditem_str(w_dict, attr)
         return None
 
-    def getdictvalue_attr_is_in_class(self, space, attr):
-        return self.getdictvalue(space, attr)
-
-    def setdictvalue(self, space, attr, w_value, shadows_type=True):
+    def setdictvalue(self, space, attr, w_value):
         w_dict = self.getdict()
         if w_dict is not None:
-            space.setitem_str(w_dict, attr, w_value, shadows_type)
+            space.setitem_str(w_dict, attr, w_value)
             return True
         return False
 
@@ -261,10 +258,9 @@
 
         self.interned_strings = {}
         self.actionflag = ActionFlag()    # changed by the signal module
+        self.check_signal_action = None   # changed by the signal module
         self.user_del_action = UserDelAction(self)
         self.frame_trace_action = FrameTraceAction(self)
-        self.actionflag.register_action(self.user_del_action)
-        self.actionflag.register_action(self.frame_trace_action)
 
         from pypy.interpreter.pycode import cpython_magic, default_magic
         self.our_magic = default_magic
@@ -657,7 +653,7 @@
         """shortcut for space.int_w(space.hash(w_obj))"""
         return self.int_w(self.hash(w_obj))
 
-    def setitem_str(self, w_obj, key, w_value, shadows_type=True):
+    def setitem_str(self, w_obj, key, w_value):
         return self.setitem(w_obj, self.wrap(key), w_value)
 
     def finditem_str(self, w_obj, key):

Modified: pypy/branch/fast-forward/pypy/interpreter/executioncontext.py
==============================================================================
--- pypy/branch/fast-forward/pypy/interpreter/executioncontext.py	(original)
+++ pypy/branch/fast-forward/pypy/interpreter/executioncontext.py	Tue Nov  9 00:03:02 2010
@@ -5,6 +5,8 @@
 from pypy.rlib.unroll import unrolling_iterable
 from pypy.rlib import jit
 
+TICK_COUNTER_STEP = 100
+
 def app_profile_call(space, w_callable, frame, event, w_arg):
     space.call_function(w_callable,
                         space.wrap(frame),
@@ -19,6 +21,9 @@
     # XXX   self.w_tracefunc, self.profilefunc
     # XXX   frame.is_being_profiled
 
+    # XXX [fijal] but they're not. is_being_profiled is guarded a bit all
+    #     over the place as well as w_tracefunc
+
     def __init__(self, space):
         self.space = space
         self.topframeref = jit.vref_None
@@ -163,24 +168,19 @@
         if self.w_tracefunc is not None:
             self._trace(frame, 'return', w_retval)
 
-    def bytecode_trace(self, frame):
+    def bytecode_trace(self, frame, decr_by=TICK_COUNTER_STEP):
         "Trace function called before each bytecode."
         # this is split into a fast path and a slower path that is
         # not invoked every time bytecode_trace() is.
         actionflag = self.space.actionflag
-        ticker = actionflag.get()
-        if actionflag.has_bytecode_counter:    # this "if" is constant-folded
-            ticker += 1
-            actionflag.set(ticker)
-        if ticker & actionflag.interesting_bits:  # fast check
+        if actionflag.decrement_ticker(decr_by) < 0:
             actionflag.action_dispatcher(self, frame)     # slow path
     bytecode_trace._always_inline_ = True
 
     def bytecode_trace_after_exception(self, frame):
         "Like bytecode_trace(), but without increasing the ticker."
         actionflag = self.space.actionflag
-        ticker = actionflag.get()
-        if ticker & actionflag.interesting_bits:  # fast check
+        if actionflag.get_ticker() < 0:
             actionflag.action_dispatcher(self, frame)     # slow path
     bytecode_trace_after_exception._always_inline_ = True
 
@@ -314,125 +314,109 @@
                 frame.last_exception = last_exception
                 self.is_tracing -= 1
 
+    def checksignals(self):
+        """Similar to PyErr_CheckSignals().  If called in the main thread,
+        and if signals are pending for the process, deliver them now
+        (i.e. call the signal handlers)."""
+        if self.space.check_signal_action is not None:
+            self.space.check_signal_action.perform(self, None)
+
     def _freeze_(self):
         raise Exception("ExecutionContext instances should not be seen during"
                         " translation.  Now is a good time to inspect the"
                         " traceback and see where this one comes from :-)")
 
 
-class AbstractActionFlag:
-    """This holds the global 'action flag'.  It is a single bitfield
-    integer, with bits corresponding to AsyncAction objects that need to
-    be immediately triggered.  The correspondance from bits to
-    AsyncAction instances is built at translation time.  We can quickly
-    check if there is anything at all to do by checking if any of the
-    relevant bits is set.  If threads are enabled, they consume the 20
-    lower bits to hold a counter incremented at each bytecode, to know
-    when to release the GIL.
+class AbstractActionFlag(object):
+    """This holds in an integer the 'ticker'.  If threads are enabled,
+    it is decremented at each bytecode; when it reaches zero, we release
+    the GIL.  And whether we have threads or not, it is forced to zero
+    whenever we fire any of the asynchronous actions.
     """
     def __init__(self):
         self._periodic_actions = []
         self._nonperiodic_actions = []
-        self.unused_bits = self.FREE_BITS[:]
         self.has_bytecode_counter = False
-        self.interesting_bits = 0
+        self.fired_actions = None
+        self.checkinterval_scaled = 100 * TICK_COUNTER_STEP
         self._rebuild_action_dispatcher()
 
     def fire(self, action):
-        """Request for the action to be run before the next opcode.
-        The action must have been registered at space initalization time."""
-        ticker = self.get()
-        self.set(ticker | action.bitmask)
-
-    def register_action(self, action):
-        "NOT_RPYTHON"
-        assert isinstance(action, AsyncAction)
-        if action.bitmask == 0:
-            while True:
-                action.bitmask = self.unused_bits.pop(0)
-                if not (action.bitmask & self.interesting_bits):
-                    break
-        self.interesting_bits |= action.bitmask
-        if action.bitmask & self.BYTECODE_COUNTER_OVERFLOW_BIT:
-            assert action.bitmask == self.BYTECODE_COUNTER_OVERFLOW_BIT
-            self._periodic_actions.append(action)
+        """Request for the action to be run before the next opcode."""
+        if not action._fired:
+            action._fired = True
+            if self.fired_actions is None:
+                self.fired_actions = []
+            self.fired_actions.append(action)
+            # set the ticker to -1 in order to force action_dispatcher()
+            # to run at the next possible bytecode
+            self.reset_ticker(-1)
+
+    def register_periodic_action(self, action, use_bytecode_counter):
+        """NOT_RPYTHON:
+        Register the PeriodicAsyncAction action to be called whenever the
+        tick counter becomes smaller than 0.  If 'use_bytecode_counter' is
+        True, make sure that we decrease the tick counter at every bytecode.
+        This is needed for threads.  Note that 'use_bytecode_counter' can be
+        False for signal handling, because whenever the process receives a
+        signal, the tick counter is set to -1 by C code in signals.h.
+        """
+        assert isinstance(action, PeriodicAsyncAction)
+        self._periodic_actions.append(action)
+        if use_bytecode_counter:
             self.has_bytecode_counter = True
-            self.force_tick_counter()
-        else:
-            self._nonperiodic_actions.append((action, action.bitmask))
         self._rebuild_action_dispatcher()
 
-    def setcheckinterval(self, space, interval):
-        if interval < self.CHECK_INTERVAL_MIN:
-            interval = self.CHECK_INTERVAL_MIN
-        elif interval > self.CHECK_INTERVAL_MAX:
-            interval = self.CHECK_INTERVAL_MAX
-        space.sys.checkinterval = interval
-        self.force_tick_counter()
-
-    def force_tick_counter(self):
-        # force the tick counter to a valid value -- this actually forces
-        # it to reach BYTECODE_COUNTER_OVERFLOW_BIT at the next opcode.
-        ticker = self.get()
-        ticker &= ~ self.BYTECODE_COUNTER_OVERFLOW_BIT
-        ticker |= self.BYTECODE_COUNTER_MASK
-        self.set(ticker)
+    def getcheckinterval(self):
+        return self.checkinterval_scaled // TICK_COUNTER_STEP
+
+    def setcheckinterval(self, interval):
+        MAX = sys.maxint // TICK_COUNTER_STEP
+        if interval < 1:
+            interval = 1
+        elif interval > MAX:
+            interval = MAX
+        self.checkinterval_scaled = interval * TICK_COUNTER_STEP
 
     def _rebuild_action_dispatcher(self):
         periodic_actions = unrolling_iterable(self._periodic_actions)
-        nonperiodic_actions = unrolling_iterable(self._nonperiodic_actions)
-        has_bytecode_counter = self.has_bytecode_counter
 
         @jit.dont_look_inside
         def action_dispatcher(ec, frame):
-            # periodic actions
-            if has_bytecode_counter:
-                ticker = self.get()
-                if ticker & self.BYTECODE_COUNTER_OVERFLOW_BIT:
-                    # We must run the periodic actions now, but first
-                    # reset the bytecode counter (the following line
-                    # works by assuming that we just overflowed the
-                    # counter, i.e. BYTECODE_COUNTER_OVERFLOW_BIT is
-                    # set but none of the BYTECODE_COUNTER_MASK bits
-                    # are).
-                    ticker -= ec.space.sys.checkinterval
-                    self.set(ticker)
-                    for action in periodic_actions:
-                        action.perform(ec, frame)
+            # periodic actions (first reset the bytecode counter)
+            self.reset_ticker(self.checkinterval_scaled)
+            for action in periodic_actions:
+                action.perform(ec, frame)
 
             # nonperiodic actions
-            for action, bitmask in nonperiodic_actions:
-                ticker = self.get()
-                if ticker & bitmask:
-                    self.set(ticker & ~ bitmask)
+            list = self.fired_actions
+            if list is not None:
+                self.fired_actions = None
+                for action in list:
+                    action._fired = False
                     action.perform(ec, frame)
 
         action_dispatcher._dont_inline_ = True
         self.action_dispatcher = action_dispatcher
 
-    # Bits reserved for the bytecode counter, if used
-    BYTECODE_COUNTER_MASK = (1 << 20) - 1
-    BYTECODE_COUNTER_OVERFLOW_BIT = (1 << 20)
-
-    # Free bits
-    FREE_BITS = [1 << _b for _b in range(21, LONG_BIT-1)]
-
-    # The acceptable range of values for sys.checkinterval, so that
-    # the bytecode_counter fits in 20 bits
-    CHECK_INTERVAL_MIN = 1
-    CHECK_INTERVAL_MAX = BYTECODE_COUNTER_OVERFLOW_BIT
-
 
 class ActionFlag(AbstractActionFlag):
     """The normal class for space.actionflag.  The signal module provides
     a different one."""
-    _flags = 0
+    _ticker = 0
+
+    def get_ticker(self):
+        return self._ticker
 
-    def get(self):
-        return self._flags
+    def reset_ticker(self, value):
+        self._ticker = value
 
-    def set(self, value):
-        self._flags = value
+    def decrement_ticker(self, by):
+        value = self._ticker
+        if self.has_bytecode_counter:    # this 'if' is constant-folded
+            value -= by
+            self._ticker = value
+        return value
 
 
 class AsyncAction(object):
@@ -440,7 +424,7 @@
     asynchronously with regular bytecode execution, but that still need
     to occur between two opcodes, not at a completely random time.
     """
-    bitmask = 0      # means 'please choose one bit automatically'
+    _fired = False
 
     def __init__(self, space):
         self.space = space
@@ -453,10 +437,11 @@
     def fire_after_thread_switch(self):
         """Bit of a hack: fire() the action but only the next time the GIL
         is released and re-acquired (i.e. after a potential thread switch).
-        Don't call this if threads are not enabled.
+        Don't call this if threads are not enabled.  Currently limited to
+        one action (i.e. reserved for CheckSignalAction from module/signal).
         """
         from pypy.module.thread.gil import spacestate
-        spacestate.set_actionflag_bit_after_thread_switch |= self.bitmask
+        spacestate.action_after_thread_switch = self
 
     def perform(self, executioncontext, frame):
         """To be overridden."""
@@ -466,7 +451,6 @@
     """Abstract base class for actions that occur automatically
     every sys.checkinterval bytecodes.
     """
-    bitmask = ActionFlag.BYTECODE_COUNTER_OVERFLOW_BIT
 
 
 class UserDelAction(AsyncAction):

Modified: pypy/branch/fast-forward/pypy/interpreter/gateway.py
==============================================================================
--- pypy/branch/fast-forward/pypy/interpreter/gateway.py	(original)
+++ pypy/branch/fast-forward/pypy/interpreter/gateway.py	Tue Nov  9 00:03:02 2010
@@ -28,7 +28,7 @@
 # internal non-translatable parts: 
 import py
 
-class SignatureBuilder:
+class SignatureBuilder(object):
     "NOT_RPYTHON"
     def __init__(self, func=None, argnames=None, varargname=None,
                  kwargname=None, name = None):
@@ -51,7 +51,7 @@
 
 #________________________________________________________________
 
-class UnwrapSpecRecipe:
+class UnwrapSpecRecipe(object):
     "NOT_RPYTHON"
 
     bases_order = [Wrappable, W_Root, ObjSpace, Arguments, object]

Modified: pypy/branch/fast-forward/pypy/interpreter/pyopcode.py
==============================================================================
--- pypy/branch/fast-forward/pypy/interpreter/pyopcode.py	(original)
+++ pypy/branch/fast-forward/pypy/interpreter/pyopcode.py	Tue Nov  9 00:03:02 2010
@@ -1244,7 +1244,7 @@
     state_pack_variables = staticmethod(state_pack_variables)
 
 
-class FrameBlock:
+class FrameBlock(object):
 
     """Abstract base class for frame blocks from the blockstack,
     used by the SETUP_XXX and POP_BLOCK opcodes."""

Modified: pypy/branch/fast-forward/pypy/interpreter/test/test_executioncontext.py
==============================================================================
--- pypy/branch/fast-forward/pypy/interpreter/test/test_executioncontext.py	(original)
+++ pypy/branch/fast-forward/pypy/interpreter/test/test_executioncontext.py	Tue Nov  9 00:03:02 2010
@@ -19,7 +19,6 @@
 
         space = self.space
         a1 = DemoAction(space)
-        space.actionflag.register_action(a1)
         for i in range(20):
             # assert does not raise:
             space.appexec([], """():
@@ -50,7 +49,7 @@
 
         space = self.space
         a2 = DemoAction(space)
-        space.actionflag.register_action(a2)
+        space.actionflag.register_periodic_action(a2, True)
         try:
             for i in range(500):
                 space.appexec([], """():
@@ -59,7 +58,8 @@
                 """)
         except Finished:
             pass
-        assert space.sys.checkinterval / 10 < i < space.sys.checkinterval * 3
+        checkinterval = space.actionflag.getcheckinterval()
+        assert checkinterval / 10 < i < checkinterval * 1.1
 
     def test_llprofile(self):
         l = []

Modified: pypy/branch/fast-forward/pypy/interpreter/typedef.py
==============================================================================
--- pypy/branch/fast-forward/pypy/interpreter/typedef.py	(original)
+++ pypy/branch/fast-forward/pypy/interpreter/typedef.py	Tue Nov  9 00:03:02 2010
@@ -197,6 +197,7 @@
         from pypy.objspace.std.mapdict import BaseMapdictObject, ObjectMixin
         add(BaseMapdictObject)
         add(ObjectMixin)
+        body["user_overridden_class"] = True
         features = ()
 
     if "user" in features:     # generic feature needed by all subcls
@@ -256,16 +257,7 @@
                 return self.slots_w[index]
         add(Proto)
 
-    wantdict = "dict" in features
-    if wantdict and config.objspace.std.withinlineddict:
-        from pypy.objspace.std.objectobject import W_ObjectObject
-        from pypy.objspace.std.inlinedict import make_mixin
-        if supercls is W_ObjectObject:
-            Mixin = make_mixin(config)
-            add(Mixin)
-            wantdict = False
-
-    if wantdict:
+    if "dict" in features:
         base_user_setup = supercls.user_setup.im_func
         if "user_setup" in body:
             base_user_setup = body["user_setup"]
@@ -284,15 +276,6 @@
             def setclass(self, space, w_subtype):
                 # only used by descr_set___class__
                 self.w__class__ = w_subtype
-                if space.config.objspace.std.withshadowtracking:
-                    self.w__dict__.set_shadows_anything()
-
-            def getdictvalue_attr_is_in_class(self, space, name):
-                w_dict = self.w__dict__
-                if space.config.objspace.std.withshadowtracking:
-                    if not w_dict.shadows_anything():
-                        return None
-                return space.finditem_str(w_dict, name)
 
         add(Proto)
 

Modified: pypy/branch/fast-forward/pypy/jit/backend/detect_cpu.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/backend/detect_cpu.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/backend/detect_cpu.py	Tue Nov  9 00:03:02 2010
@@ -23,11 +23,6 @@
         mach = os.popen('uname -m', 'r').read().strip()
         if not mach:
             raise ProcessorAutodetectError, "cannot run 'uname -m'"
-    if mach == 'x86_64':
-        if sys.maxint == 2147483647:
-            mach = 'x86'     # it's a 64-bit processor but in 32-bits mode, maybe
-        else:
-            assert sys.maxint == 2 ** 63 - 1
     try:
         return {'i386': 'x86',
                 'i486': 'x86',
@@ -36,17 +31,31 @@
                 'i86pc': 'x86',    # Solaris/Intel
                 'x86':   'x86',    # Apple
                 'Power Macintosh': 'ppc',
-                'x86_64': 'x86_64', 
+                'x86_64': 'x86', 
                 }[mach]
     except KeyError:
-        raise ProcessorAutodetectError, "unsupported processor '%s'" % mach
+        return mach
+
+def autodetect_main_model_and_size():
+    model = autodetect_main_model()
+    if sys.maxint == 2**31-1:
+        model += '_32'
+    elif sys.maxint == 2**63-1:
+        model += '_64'
+    else:
+        raise AssertionError, "bad value for sys.maxint"
+    return model
 
 def autodetect():
     model = autodetect_main_model()
-    if model == 'x86':
-        from pypy.jit.backend.x86.detect_sse2 import detect_sse2
-        if not detect_sse2():
-            model = 'x86-without-sse2'
+    if sys.maxint == 2**63-1:
+        model += '_64'
+    else:
+        assert sys.maxint == 2**31-1
+        if model == 'x86':
+            from pypy.jit.backend.x86.detect_sse2 import detect_sse2
+            if not detect_sse2():
+                model = 'x86-without-sse2'
     return model
 
 def getcpuclassname(backend_name="auto"):

Modified: pypy/branch/fast-forward/pypy/jit/backend/llgraph/llimpl.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/backend/llgraph/llimpl.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/backend/llgraph/llimpl.py	Tue Nov  9 00:03:02 2010
@@ -152,7 +152,7 @@
     'unicodegetitem'  : (('ref', 'int'), 'int'),
     'unicodesetitem'  : (('ref', 'int', 'int'), 'int'),
     'cast_ptr_to_int' : (('ref',), 'int'),
-    'debug_merge_point': (('ref',), None),
+    'debug_merge_point': (('ref', 'int'), None),
     'force_token'     : ((), 'int'),
     'call_may_force'  : (('int', 'varargs'), 'intorptr'),
     'guard_not_forced': ((), None),
@@ -568,7 +568,7 @@
         #
         return _op_default_implementation
 
-    def op_debug_merge_point(self, _, value):
+    def op_debug_merge_point(self, _, value, recdepth):
         from pypy.jit.metainterp.warmspot import get_stats
         loc = ConstPtr(value)._get_str()
         get_stats().add_merge_point_location(loc)

Modified: pypy/branch/fast-forward/pypy/jit/backend/llgraph/runner.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/backend/llgraph/runner.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/backend/llgraph/runner.py	Tue Nov  9 00:03:02 2010
@@ -118,13 +118,13 @@
             self._descrs[key] = descr
             return descr
 
-    def compile_bridge(self, faildescr, inputargs, operations):
+    def compile_bridge(self, faildescr, inputargs, operations, log=True):
         c = llimpl.compile_start()
         self._compile_loop_or_bridge(c, inputargs, operations)
         old, oldindex = faildescr._compiled_fail
         llimpl.compile_redirect_fail(old, oldindex, c)
 
-    def compile_loop(self, inputargs, operations, loopdescr):
+    def compile_loop(self, inputargs, operations, loopdescr, log=True):
         """In a real assembler backend, this should assemble the given
         list of operations.  Here we just generate a similar CompiledLoop
         instance.  The code here is RPython, whereas the code in llimpl

Modified: pypy/branch/fast-forward/pypy/jit/backend/llsupport/test/test_gc.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/backend/llsupport/test/test_gc.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/backend/llsupport/test/test_gc.py	Tue Nov  9 00:03:02 2010
@@ -270,7 +270,7 @@
 
     def test_get_rid_of_debug_merge_point(self):
         operations = [
-            ResOperation(rop.DEBUG_MERGE_POINT, ['dummy'], None),
+            ResOperation(rop.DEBUG_MERGE_POINT, ['dummy', 2], None),
             ]
         gc_ll_descr = self.gc_ll_descr
         gc_ll_descr.rewrite_assembler(None, operations)

Modified: pypy/branch/fast-forward/pypy/jit/backend/model.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/backend/model.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/backend/model.py	Tue Nov  9 00:03:02 2010
@@ -33,14 +33,14 @@
         pass
 
 
-    def compile_loop(self, inputargs, operations, looptoken):
+    def compile_loop(self, inputargs, operations, looptoken, log=True):
         """Assemble the given loop.
         Extra attributes should be put in the LoopToken to
         point to the compiled loop in assembler.
         """
         raise NotImplementedError
 
-    def compile_bridge(self, faildescr, inputargs, operations):
+    def compile_bridge(self, faildescr, inputargs, operations, log=True):
         """Assemble the bridge.
         The FailDescr is the descr of the original guard that failed.
         """

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	Tue Nov  9 00:03:02 2010
@@ -295,7 +295,7 @@
         self.mc.RET()
         self.mc.done()
 
-    def assemble_loop(self, inputargs, operations, looptoken):
+    def assemble_loop(self, inputargs, operations, looptoken, log):
         """adds the following attributes to looptoken:
                _x86_loop_code       (an integer giving an address)
                _x86_bootstrap_code  (an integer giving an address)
@@ -303,6 +303,7 @@
                _x86_frame_depth
                _x86_param_depth
                _x86_arglocs
+               _x86_debug_checksum
         """
         if not we_are_translated():
             # Arguments should be unique
@@ -310,10 +311,11 @@
 
         self.setup()
         funcname = self._find_debug_merge_point(operations)
-
+        if log:
+            self._register_counter()
+            operations = self._inject_debugging_code(looptoken, operations)
         
         regalloc = RegAlloc(self, self.cpu.translate_support_code)
-        operations = self._inject_debugging_code(operations)
         arglocs = regalloc.prepare_loop(inputargs, operations, looptoken)
         looptoken._x86_arglocs = arglocs
 
@@ -335,18 +337,22 @@
         self._assemble_bootstrap_direct_call(arglocs, curadr,
                                              frame_depth+param_depth)
         #
-        debug_print("Loop #", looptoken.number, "has address",
-                    looptoken._x86_loop_code, "to", self.mc.tell())
+        debug_print("Loop #%d has address %x to %x" % (looptoken.number,
+                                                       looptoken._x86_loop_code,
+                                                       self.mc.tell()))
         self.mc.end_function()
         self.write_pending_failure_recoveries()
         
-    def assemble_bridge(self, faildescr, inputargs, operations):
+    def assemble_bridge(self, faildescr, inputargs, operations, log):
         if not we_are_translated():
             # Arguments should be unique
             assert len(set(inputargs)) == len(inputargs)
 
         self.setup()
         funcname = self._find_debug_merge_point(operations)
+        if log:
+            self._register_counter()
+            operations = self._inject_debugging_code(faildescr, operations)
 
         arglocs = self.rebuild_faillocs_from_descr(
             faildescr._x86_failure_recovery_bytecode)
@@ -354,7 +360,6 @@
             assert ([loc.assembler() for loc in arglocs] ==
                     [loc.assembler() for loc in faildescr._x86_debug_faillocs])
         regalloc = RegAlloc(self, self.cpu.translate_support_code)
-        operations = self._inject_debugging_code(operations)
         fail_depths = faildescr._x86_current_depths
         regalloc.prepare_bridge(fail_depths, inputargs, arglocs,
                                 operations)
@@ -374,9 +379,8 @@
             faildescr._x86_bridge_param_depth = param_depth
         # patch the jump from original guard
         self.patch_jump_for_descr(faildescr, adr_bridge)
-        debug_print("Bridge out of guard",
-                    descr_number,
-                    "has address", adr_bridge, "to", self.mc.tell())
+        debug_print("Bridge out of guard %d has address %x to %x" %
+                    (descr_number, adr_bridge, self.mc.tell()))
         self.mc.end_function()
         self.write_pending_failure_recoveries()
 
@@ -401,12 +405,14 @@
         else:
             funcname = "<loop %d>" % len(self.loop_run_counters)
         # invent the counter, so we don't get too confused
+        return funcname
+
+    def _register_counter(self):
         if self._debug:
             struct = lltype.malloc(DEBUG_COUNTER, flavor='raw',
                                    track_allocation=False)   # known to leak
             struct.i = 0
             self.loop_run_counters.append((len(self.loop_run_counters), struct))
-        return funcname
         
     def patch_jump_for_descr(self, faildescr, adr_new_target):
         adr_jump_offset = faildescr._x86_adr_jump_offset
@@ -427,9 +433,14 @@
 
         mc.done()
 
-    def _inject_debugging_code(self, operations):
+    @specialize.argtype(1)
+    def _inject_debugging_code(self, looptoken, operations):
         if self._debug:
             # before doing anything, let's increase a counter
+            s = 0
+            for op in operations:
+                s += op.getopnum()
+            looptoken._x86_debug_checksum = s
             c_adr = ConstInt(rffi.cast(lltype.Signed,
                                      self.loop_run_counters[-1][1]))
             box = BoxInt()
@@ -706,9 +717,11 @@
             dispatch_opnum = guard_opnum
         else:
             dispatch_opnum = op.getopnum()
-        res = genop_guard_list[dispatch_opnum](self, op, guard_op, guard_token,
-                                               arglocs, resloc)
-        faildescr._x86_adr_jump_offset = res
+        genop_guard_list[dispatch_opnum](self, op, guard_op, guard_token,
+                                         arglocs, resloc)
+        if not we_are_translated():
+            # must be added by the genop_guard_list[]()
+            assert hasattr(faildescr, '_x86_adr_jump_offset')
 
     def regalloc_perform_guard(self, guard_op, faillocs, arglocs, resloc,
                                current_depths):
@@ -765,15 +778,15 @@
             if isinstance(op.getarg(0), Const):
                 self.mc.CMP(arglocs[1], arglocs[0])
                 if guard_opnum == rop.GUARD_FALSE:
-                    return self.implement_guard(guard_token, rev_cond)
+                    self.implement_guard(guard_token, rev_cond)
                 else:
-                    return self.implement_guard(guard_token, false_rev_cond)
+                    self.implement_guard(guard_token, false_rev_cond)
             else:
                 self.mc.CMP(arglocs[0], arglocs[1])
                 if guard_opnum == rop.GUARD_FALSE:
-                    return self.implement_guard(guard_token, cond)
+                    self.implement_guard(guard_token, cond)
                 else:
-                    return self.implement_guard(guard_token, false_cond)
+                    self.implement_guard(guard_token, false_cond)
         return genop_cmp_guard
 
     def _cmpop_guard_float(cond, false_cond, need_jp):
@@ -787,13 +800,14 @@
             if guard_opnum == rop.GUARD_FALSE:
                 if need_jp:
                     self.mc.J_il8(rx86.Conditions['P'], 6)
-                return self.implement_guard(guard_token, cond)
+                self.implement_guard(guard_token, cond)
             else:
                 if need_jp:
                     self.mc.J_il8(rx86.Conditions['P'], 2)
                     self.mc.J_il8(rx86.Conditions[cond], 5)
-                    return self.implement_guard(guard_token)
-                return self.implement_guard(guard_token, false_cond)
+                    self.implement_guard(guard_token)
+                else:
+                    self.implement_guard(guard_token, false_cond)
         return genop_cmp_guard_float
 
     def _emit_call(self, x, arglocs, start=0, tmp=eax):
@@ -955,11 +969,11 @@
         self.mc.ensure_bytes_available(16 + guard_token.recovery_stub_size())
         if guard_opnum == rop.GUARD_TRUE:
             self.mc.J_il8(rx86.Conditions['P'], 6)
-            return self.implement_guard(guard_token, 'E')
+            self.implement_guard(guard_token, 'E')
         else:
             self.mc.J_il8(rx86.Conditions['P'], 2)
             self.mc.J_il8(rx86.Conditions['E'], 5)
-            return self.implement_guard(guard_token)
+            self.implement_guard(guard_token)
 
     def genop_float_neg(self, op, arglocs, resloc):
         # Following what gcc does: res = x ^ 0x8000000000000000
@@ -979,9 +993,9 @@
         guard_opnum = guard_op.getopnum()
         self.mc.CMP(arglocs[0], imm0)
         if guard_opnum == rop.GUARD_TRUE:
-            return self.implement_guard(guard_token, 'Z')
+            self.implement_guard(guard_token, 'Z')
         else:
-            return self.implement_guard(guard_token, 'NZ')
+            self.implement_guard(guard_token, 'NZ')
 
     def genop_int_is_true(self, op, arglocs, resloc):
         self.mc.CMP(arglocs[0], imm0)
@@ -993,9 +1007,9 @@
         guard_opnum = guard_op.getopnum()
         self.mc.CMP(arglocs[0], imm0)
         if guard_opnum == rop.GUARD_TRUE:
-            return self.implement_guard(guard_token, 'NZ')
+            self.implement_guard(guard_token, 'NZ')
         else:
-            return self.implement_guard(guard_token, 'Z')
+            self.implement_guard(guard_token, 'Z')
 
     def genop_int_is_zero(self, op, arglocs, resloc):
         self.mc.CMP(arglocs[0], imm0)
@@ -1192,13 +1206,13 @@
     def genop_guard_guard_true(self, ign_1, guard_op, guard_token, locs, ign_2):
         loc = locs[0]
         self.mc.TEST(loc, loc)
-        return self.implement_guard(guard_token, 'Z')
+        self.implement_guard(guard_token, 'Z')
     genop_guard_guard_nonnull = genop_guard_guard_true
 
     def genop_guard_guard_no_exception(self, ign_1, guard_op, guard_token,
                                        locs, ign_2):
         self.mc.CMP(heap(self.cpu.pos_exception()), imm0)
-        return self.implement_guard(guard_token, 'NZ')
+        self.implement_guard(guard_token, 'NZ')
 
     def genop_guard_guard_exception(self, ign_1, guard_op, guard_token,
                                     locs, resloc):
@@ -1206,19 +1220,18 @@
         loc1 = locs[1]
         self.mc.MOV(loc1, heap(self.cpu.pos_exception()))
         self.mc.CMP(loc1, loc)
-        addr = self.implement_guard(guard_token, 'NE')
+        self.implement_guard(guard_token, 'NE')
         if resloc is not None:
             self.mc.MOV(resloc, heap(self.cpu.pos_exc_value()))
         self.mc.MOV(heap(self.cpu.pos_exception()), imm0)
         self.mc.MOV(heap(self.cpu.pos_exc_value()), imm0)
-        return addr
 
     def _gen_guard_overflow(self, guard_op, guard_token):
         guard_opnum = guard_op.getopnum()
         if guard_opnum == rop.GUARD_NO_OVERFLOW:
-            return self.implement_guard(guard_token, 'O')
+            self.implement_guard(guard_token, 'O')
         elif guard_opnum == rop.GUARD_OVERFLOW:
-            return self.implement_guard(guard_token, 'NO')
+            self.implement_guard(guard_token, 'NO')
         else:
             not_implemented("int_xxx_ovf followed by %s" %
                             guard_op.getopname())
@@ -1238,7 +1251,7 @@
     def genop_guard_guard_false(self, ign_1, guard_op, guard_token, locs, ign_2):
         loc = locs[0]
         self.mc.TEST(loc, loc)
-        return self.implement_guard(guard_token, 'NZ')
+        self.implement_guard(guard_token, 'NZ')
     genop_guard_guard_isnull = genop_guard_guard_false
 
     def genop_guard_guard_value(self, ign_1, guard_op, guard_token, locs, ign_2):
@@ -1247,7 +1260,7 @@
             self.mc.UCOMISD(locs[0], locs[1])
         else:
             self.mc.CMP(locs[0], locs[1])
-        return self.implement_guard(guard_token, 'NE')
+        self.implement_guard(guard_token, 'NE')
 
     def _cmp_guard_class(self, locs):
         offset = self.cpu.vtable_offset
@@ -1279,7 +1292,7 @@
     def genop_guard_guard_class(self, ign_1, guard_op, guard_token, locs, ign_2):
         self.mc.ensure_bytes_available(256)
         self._cmp_guard_class(locs)
-        return self.implement_guard(guard_token, 'NE')
+        self.implement_guard(guard_token, 'NE')
 
     def genop_guard_guard_nonnull_class(self, ign_1, guard_op,
                                         guard_token, locs, ign_2):
@@ -1294,7 +1307,7 @@
         assert 0 < offset <= 127
         self.mc.overwrite(jb_location-1, [chr(offset)])
         #
-        return self.implement_guard(guard_token, 'NE')
+        self.implement_guard(guard_token, 'NE')
 
     def implement_guard_recovery(self, guard_opnum, faildescr, failargs,
                                                                fail_locs):
@@ -1621,13 +1634,15 @@
     def implement_guard(self, guard_token, condition=None):
         self.mc.reserve_bytes(guard_token.recovery_stub_size())
         self.pending_guard_tokens.append(guard_token)
-        # XXX: These jumps are patched later, the self.mc.tell() are just
-        # dummy values
+        # These jumps are patched later, the mc.tell() are just
+        # dummy values.  Also, use self.mc._mc to avoid triggering a
+        # "buffer full" exactly here.
+        mc = self.mc._mc
         if condition:
-            self.mc.J_il(rx86.Conditions[condition], self.mc.tell())
+            mc.J_il(rx86.Conditions[condition], mc.tell())
         else:
-            self.mc.JMP_l(self.mc.tell())
-        return self.mc.tell() - 4
+            mc.JMP_l(mc.tell())
+        guard_token.faildescr._x86_adr_jump_offset = mc.tell() - 4
 
     def genop_call(self, op, arglocs, resloc):
         sizeloc = arglocs[0]
@@ -1668,7 +1683,7 @@
         self.mc.MOV_bi(FORCE_INDEX_OFS, fail_index)
         self.genop_call(op, arglocs, result_loc)
         self.mc.CMP_bi(FORCE_INDEX_OFS, 0)
-        return self.implement_guard(guard_token, 'L')
+        self.implement_guard(guard_token, 'L')
 
     def genop_guard_call_assembler(self, op, guard_op, guard_token,
                                    arglocs, result_loc):
@@ -1755,7 +1770,7 @@
         assert 0 <= offset <= 127
         self.mc.overwrite(jmp_location - 1, [chr(offset)])
         self.mc.CMP_bi(FORCE_INDEX_OFS, 0)
-        return self.implement_guard(guard_token, 'L')
+        self.implement_guard(guard_token, 'L')
 
     def genop_discard_cond_call_gc_wb(self, op, arglocs):
         # use 'mc._mc' directly instead of 'mc', to avoid

Modified: pypy/branch/fast-forward/pypy/jit/backend/x86/runner.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/backend/x86/runner.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/backend/x86/runner.py	Tue Nov  9 00:03:02 2010
@@ -49,11 +49,13 @@
         self.assembler.finish_once()
         self.profile_agent.shutdown()
 
-    def compile_loop(self, inputargs, operations, looptoken):
-        self.assembler.assemble_loop(inputargs, operations, looptoken)
-
-    def compile_bridge(self, faildescr, inputargs, operations):
-        self.assembler.assemble_bridge(faildescr, inputargs, operations)
+    def compile_loop(self, inputargs, operations, looptoken, log=True):
+        self.assembler.assemble_loop(inputargs, operations, looptoken,
+                                     log=log)
+
+    def compile_bridge(self, faildescr, inputargs, operations, log=True):
+        self.assembler.assemble_bridge(faildescr, inputargs, operations,
+                                       log=log)
 
     def set_future_value_int(self, index, intvalue):
         self.assembler.fail_boxes_int.setitem(index, intvalue)

Modified: pypy/branch/fast-forward/pypy/jit/backend/x86/test/test_runner.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/backend/x86/test/test_runner.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/backend/x86/test/test_runner.py	Tue Nov  9 00:03:02 2010
@@ -346,7 +346,7 @@
                 return self.val
 
         operations = [
-            ResOperation(rop.DEBUG_MERGE_POINT, [FakeString("hello")], None),
+            ResOperation(rop.DEBUG_MERGE_POINT, [FakeString("hello"), 0], None),
             ResOperation(rop.INT_ADD, [i0, ConstInt(1)], i1),
             ResOperation(rop.INT_LE, [i1, ConstInt(9)], i2),
             ResOperation(rop.GUARD_TRUE, [i2], None, descr=faildescr1),
@@ -365,7 +365,7 @@
         bridge = [
             ResOperation(rop.INT_LE, [i1b, ConstInt(19)], i3),
             ResOperation(rop.GUARD_TRUE, [i3], None, descr=faildescr2),
-            ResOperation(rop.DEBUG_MERGE_POINT, [FakeString("bye")], None),
+            ResOperation(rop.DEBUG_MERGE_POINT, [FakeString("bye"), 0], None),
             ResOperation(rop.JUMP, [i1b], None, descr=looptoken),
         ]
         bridge[1].setfailargs([i1b])
@@ -478,6 +478,10 @@
             # whether the test segfaults.
             assert self.cpu.get_latest_value_int(0) == finished.value
 
+    def test_overflow_guard_exception(self):
+        for i in range(50):
+            self.test_exceptions()
+
 
 class TestDebuggingAssembler(object):
     def setup_method(self, meth):
@@ -493,7 +497,7 @@
     def test_debugger_on(self):
         loop = """
         [i0]
-        debug_merge_point('xyz')
+        debug_merge_point('xyz', 0)
         i1 = int_add(i0, 1)
         i2 = int_ge(i1, 10)
         guard_false(i2) []
@@ -511,3 +515,20 @@
         self.cpu.finish_once()
         lines = py.path.local(self.logfile + ".count").readlines()
         assert lines[0] == '0:10\n'  # '10      xyz\n'
+
+    def test_debugger_checksum(self):
+        loop = """
+        [i0]
+        debug_merge_point('xyz', 0)
+        i1 = int_add(i0, 1)
+        i2 = int_ge(i1, 10)
+        guard_false(i2) []
+        jump(i1)
+        """
+        ops = parse(loop)
+        self.cpu.assembler.set_debug(True)
+        self.cpu.compile_loop(ops.inputargs, ops.operations, ops.token)
+        self.cpu.set_future_value_int(0, 0)
+        self.cpu.execute_token(ops.token)
+        assert ops.token._x86_debug_checksum == sum([op.getopnum()
+                                                     for op in ops.operations])

Modified: pypy/branch/fast-forward/pypy/jit/backend/x86/tool/viewcode.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/backend/x86/tool/viewcode.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/backend/x86/tool/viewcode.py	Tue Nov  9 00:03:02 2010
@@ -37,7 +37,7 @@
         'x86_64': 'x86-64',
         'i386': 'i386',
     }
-    objdump = ('objdump -M intel,%(backend)s -b binary -m i386 '
+    objdump = ('objdump -M %(backend)s -b binary -m i386 '
                '--adjust-vma=%(origin)d -D %(file)s')
     #
     f = open(tmpfile, 'wb')

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	Tue Nov  9 00:03:02 2010
@@ -237,6 +237,8 @@
                                     effectinfo)
 
     def _canraise(self, op):
+        if op.opname == 'pseudo_call_cannot_raise':
+            return False
         try:
             return self.raise_analyzer.can_raise(op)
         except lltype.DelayedPointer:

Modified: pypy/branch/fast-forward/pypy/jit/codewriter/format.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/codewriter/format.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/codewriter/format.py	Tue Nov  9 00:03:02 2010
@@ -80,7 +80,8 @@
 
 def assert_format(ssarepr, expected):
     asm = format_assembler(ssarepr)
-    expected = str(py.code.Source(expected)).strip() + '\n'
+    if expected != '':
+        expected = str(py.code.Source(expected)).strip() + '\n'
     asmlines = asm.split("\n")
     explines = expected.split("\n")
     for asm, exp in zip(asmlines, explines):

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	Tue Nov  9 00:03:02 2010
@@ -172,6 +172,7 @@
 
     def rewrite_op_same_as(self, op): pass
     def rewrite_op_cast_pointer(self, op): pass
+    def rewrite_op_cast_opaque_ptr(self, op): pass   # rlib.rerased
     def rewrite_op_cast_primitive(self, op): pass
     def rewrite_op_cast_bool_to_int(self, op): pass
     def rewrite_op_cast_bool_to_uint(self, op): pass
@@ -872,6 +873,8 @@
         elif oopspec_name == 'jit.assert_green':
             kind = getkind(args[0].concretetype)
             return SpaceOperation('%s_assert_green' % kind, args, None)
+        elif oopspec_name == 'jit.current_trace_length':
+            return SpaceOperation('current_trace_length', [], op.result)
         else:
             raise AssertionError("missing support for %r" % oopspec_name)
 
@@ -893,17 +896,21 @@
             prefix = 'do_resizable_'
             ARRAY = LIST.items.TO
             if self._array_of_voids(ARRAY):
-                raise NotSupported("resizable lists of voids")
-            descrs = (self.cpu.arraydescrof(ARRAY),
-                      self.cpu.fielddescrof(LIST, 'length'),
-                      self.cpu.fielddescrof(LIST, 'items'),
-                      self.cpu.sizeof(LIST))
+                prefix += 'void_'
+                descrs = ()
+            else:
+                descrs = (self.cpu.arraydescrof(ARRAY),
+                          self.cpu.fielddescrof(LIST, 'length'),
+                          self.cpu.fielddescrof(LIST, 'items'),
+                          self.cpu.sizeof(LIST))
         else:
             prefix = 'do_fixed_'
             if self._array_of_voids(LIST):
-                raise NotSupported("fixed lists of voids")
-            arraydescr = self.cpu.arraydescrof(LIST)
-            descrs = (arraydescr,)
+                prefix += 'void_'
+                descrs = ()
+            else:
+                arraydescr = self.cpu.arraydescrof(LIST)
+                descrs = (arraydescr,)
         #
         try:
             meth = getattr(self, prefix + oopspec_name.replace('.', '_'))
@@ -942,6 +949,11 @@
                                              descr, args[1]], v_posindex)
             return v_posindex, [op0, op1]
 
+    def _prepare_void_list_getset(self, op):
+        non_negative, can_raise = self._get_list_nonneg_canraise_flags(op)
+        if can_raise:
+            raise NotSupported("list operation can raise")
+
     def _get_initial_newlist_length(self, op, args):
         # normalize number of arguments to the 'newlist' function
         if len(args) > 1:
@@ -1013,6 +1025,12 @@
     def do_fixed_list_ll_arraycopy(self, op, args, arraydescr):
         return self._handle_oopspec_call(op, args, EffectInfo.OS_ARRAYCOPY)
 
+    def do_fixed_void_list_getitem(self, op, args):
+        self._prepare_void_list_getset(op)
+        return []
+    do_fixed_void_list_getitem_foldable = do_fixed_void_list_getitem
+    do_fixed_void_list_setitem = do_fixed_void_list_getitem
+
     # ---------- resizable lists ----------
 
     def do_resizable_newlist(self, op, args, arraydescr, lengthdescr,
@@ -1048,6 +1066,12 @@
         return SpaceOperation('getfield_gc_i',
                               [args[0], lengthdescr], op.result)
 
+    def do_resizable_void_list_getitem(self, op, args):
+        self._prepare_void_list_getset(op)
+        return []
+    do_resizable_void_list_getitem_foldable = do_resizable_void_list_getitem
+    do_resizable_void_list_setitem = do_resizable_void_list_getitem
+
     # ----------
     # Strings and Unicodes.
 
@@ -1076,7 +1100,7 @@
         c_func, TP = support.builtin_func_for_spec(self.cpu.rtyper,
                                                    oopspec_name, argtypes,
                                                    resulttype)
-        op = SpaceOperation('pseudo_call',
+        op = SpaceOperation('pseudo_call_cannot_raise',
                             [c_func] + [varoftype(T) for T in argtypes],
                             varoftype(resulttype))
         calldescr = self.callcontrol.getcalldescr(op, oopspecindex)

Modified: pypy/branch/fast-forward/pypy/jit/codewriter/test/test_list.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/codewriter/test/test_list.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/codewriter/test/test_list.py	Tue Nov  9 00:03:02 2010
@@ -19,6 +19,7 @@
 class FakeCPU:
     class arraydescrof(AbstractDescr):
         def __init__(self, ARRAY):
+            assert ARRAY.OF != lltype.Void
             self.ARRAY = ARRAY
         def __repr__(self):
             return '<ArrayDescr>'

Modified: pypy/branch/fast-forward/pypy/jit/metainterp/blackhole.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/metainterp/blackhole.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/metainterp/blackhole.py	Tue Nov  9 00:03:02 2010
@@ -774,6 +774,10 @@
     def bhimpl_float_assert_green(x):
         pass
 
+    @arguments(returns="i")
+    def bhimpl_current_trace_length():
+        return -1
+
     # ----------
     # the main hints and recursive calls
 

Modified: pypy/branch/fast-forward/pypy/jit/metainterp/compile.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/metainterp/compile.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/metainterp/compile.py	Tue Nov  9 00:03:02 2010
@@ -123,7 +123,6 @@
     if not we_are_translated():
         show_loop(metainterp_sd)
         TreeLoop.check_consistency_of(inputargs, operations)
-        pass
     metainterp_sd.profiler.start_backend()
     debug_start("jit-backend")
     try:
@@ -600,5 +599,5 @@
         ResOperation(rop.FINISH, finishargs, None, descr=jd.portal_finishtoken)
         ]
     operations[1].setfailargs([])
-    cpu.compile_loop(inputargs, operations, loop_token)
+    cpu.compile_loop(inputargs, operations, loop_token, log=False)
     return loop_token

Modified: pypy/branch/fast-forward/pypy/jit/metainterp/logger.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/metainterp/logger.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/metainterp/logger.py	Tue Nov  9 00:03:02 2010
@@ -81,7 +81,8 @@
             op = operations[i]
             if op.getopnum() == rop.DEBUG_MERGE_POINT:
                 loc = op.getarg(0)._get_str()
-                debug_print("debug_merge_point('%s')" % (loc,))
+                reclev = op.getarg(1).getint()
+                debug_print("debug_merge_point('%s', %s)" % (loc, reclev))
                 continue
             args = ", ".join([self.repr_of_arg(memo, op.getarg(i)) for i in range(op.numargs())])
             if op.result is not None:

Modified: pypy/branch/fast-forward/pypy/jit/metainterp/optimizeopt/rewrite.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/metainterp/optimizeopt/rewrite.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/metainterp/optimizeopt/rewrite.py	Tue Nov  9 00:03:02 2010
@@ -244,14 +244,11 @@
         self.optimizer.exception_might_have_happened = False
 
     def optimize_CALL_LOOPINVARIANT(self, op):
-        funcvalue = self.getvalue(op.getarg(0))
-        if not funcvalue.is_constant():
-            # XXX this code path is never executed in tests nor in production.
-            # in fact, it can't even happen since residual_call in codewriter
-            # expects a compile-time constant
-            self.emit_operation(op)
-            return
-        key = make_hashable_int(op.getarg(0).getint())
+        arg = op.getarg(0)
+        # 'arg' must be a Const, because residual_call in codewriter
+        # expects a compile-time constant
+        assert isinstance(arg, Const)
+        key = make_hashable_int(arg.getint())
         resvalue = self.optimizer.loop_invariant_results.get(key, None)
         if resvalue is not None:
             self.make_equal_to(op.result, resvalue)

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	Tue Nov  9 00:03:02 2010
@@ -820,7 +820,8 @@
         jitdriver_sd = self.metainterp.staticdata.jitdrivers_sd[jdindex]
         self.verify_green_args(jitdriver_sd, greenboxes)
         # xxx we may disable the following line in some context later
-        self.debug_merge_point(jitdriver_sd, greenboxes)
+        self.debug_merge_point(jitdriver_sd, self.metainterp.in_recursion,
+                               greenboxes)
         if self.metainterp.seen_loop_header_for_jdindex < 0:
             if not jitdriver_sd.no_loop_header or not any_operation:
                 return
@@ -860,13 +861,13 @@
                                     assembler_call=True)
             raise ChangeFrame
 
-    def debug_merge_point(self, jitdriver_sd, greenkey):
+    def debug_merge_point(self, jitdriver_sd, in_recursion, greenkey):
         # debugging: produce a DEBUG_MERGE_POINT operation
         loc = jitdriver_sd.warmstate.get_location_str(greenkey)
         debug_print(loc)
         constloc = self.metainterp.cpu.ts.conststr(loc)
         self.metainterp.history.record(rop.DEBUG_MERGE_POINT,
-                                       [constloc], None)
+                                       [constloc, ConstInt(in_recursion)], None)
 
     @arguments("box", "label")
     def opimpl_goto_if_exception_mismatch(self, vtablebox, next_exc_target):
@@ -948,6 +949,11 @@
     opimpl_ref_assert_green   = _opimpl_assert_green
     opimpl_float_assert_green = _opimpl_assert_green
 
+    @arguments()
+    def opimpl_current_trace_length(self):
+        trace_length = len(self.metainterp.history.operations)
+        return ConstInt(trace_length)
+
     @arguments("box")
     def opimpl_virtual_ref(self, box):
         # Details on the content of metainterp.virtualref_boxes:

Modified: pypy/branch/fast-forward/pypy/jit/metainterp/resoperation.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/metainterp/resoperation.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/metainterp/resoperation.py	Tue Nov  9 00:03:02 2010
@@ -458,7 +458,7 @@
     'NEWUNICODE/1',
     #'RUNTIMENEW/1',     # ootype operation    
     'COND_CALL_GC_WB/2d', # [objptr, newvalue]   (for the write barrier)
-    'DEBUG_MERGE_POINT/1',      # debugging only
+    'DEBUG_MERGE_POINT/2',      # debugging only
     'JIT_DEBUG/*',              # debugging only
     'VIRTUAL_REF_FINISH/2',   # removed before it's passed to the backend
     'COPYSTRCONTENT/5',       # src, dst, srcstart, dststart, length

Modified: pypy/branch/fast-forward/pypy/jit/metainterp/test/test_basic.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/metainterp/test/test_basic.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/metainterp/test/test_basic.py	Tue Nov  9 00:03:02 2010
@@ -3,6 +3,7 @@
 from pypy.rlib.jit import JitDriver, we_are_jitted, hint, dont_look_inside
 from pypy.rlib.jit import OPTIMIZER_FULL, OPTIMIZER_SIMPLE, loop_invariant
 from pypy.rlib.jit import jit_debug, assert_green, AssertGreenFailed
+from pypy.rlib.jit import unroll_safe, current_trace_length
 from pypy.jit.metainterp.warmspot import ll_meta_interp, get_stats
 from pypy.jit.backend.llgraph import runner
 from pypy.jit.metainterp import pyjitpl, history
@@ -1672,6 +1673,31 @@
         assert res == 8
         py.test.raises(AssertGreenFailed, self.interp_operations, f, [8, 0])
 
+    def test_current_trace_length(self):
+        myjitdriver = JitDriver(greens = ['g'], reds = ['x'])
+        @dont_look_inside
+        def residual():
+            print "hi there"
+        @unroll_safe
+        def loop(g):
+            y = 0
+            while y < g:
+                residual()
+                y += 1
+        def f(x, g):
+            n = 0
+            while x > 0:
+                myjitdriver.can_enter_jit(x=x, g=g)
+                myjitdriver.jit_merge_point(x=x, g=g)
+                loop(g)
+                x -= 1
+                n = current_trace_length()
+            return n
+        res = self.meta_interp(f, [5, 8])
+        assert 14 < res < 42
+        res = self.meta_interp(f, [5, 2])
+        assert 4 < res < 14
+
 
 class TestOOtype(BasicTests, OOJitMixin):
 

Modified: pypy/branch/fast-forward/pypy/jit/metainterp/test/test_logger.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/metainterp/test/test_logger.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/metainterp/test/test_logger.py	Tue Nov  9 00:03:02 2010
@@ -97,7 +97,7 @@
     def test_debug_merge_point(self):
         inp = '''
         []
-        debug_merge_point("info")
+        debug_merge_point("info", 0)
         '''
         loop, oloop = self.reparse(inp, check_equal=False)
         assert loop.operations[0].getarg(0)._get_str() == 'info'

Modified: pypy/branch/fast-forward/pypy/jit/metainterp/test/test_oparser.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/metainterp/test/test_oparser.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/metainterp/test/test_oparser.py	Tue Nov  9 00:03:02 2010
@@ -141,10 +141,10 @@
 def test_debug_merge_point():
     x = '''
     []
-    debug_merge_point("info")
-    debug_merge_point('info')
-    debug_merge_point('<some ('other,')> info')
-    debug_merge_point('(stuff) #1')
+    debug_merge_point("info", 0)
+    debug_merge_point('info', 1)
+    debug_merge_point('<some ('other,')> info', 1)
+    debug_merge_point('(stuff) #1', 1)
     '''
     loop = parse(x)
     assert loop.operations[0].getarg(0)._get_str() == 'info'
@@ -168,7 +168,7 @@
 i6 = int_sub(i1, 1)
 i8 = int_gt(i6, 3)
 guard_true(i8, descr=<Guard15>) [i4, i6]
-debug_merge_point('(no jitdriver.get_printable_location!)')
+debug_merge_point('(no jitdriver.get_printable_location!)', 0)
 jump(i6, i4, descr=<Loop0>)
 '''
 

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	Tue Nov  9 00:03:02 2010
@@ -807,10 +807,10 @@
         guard_value(i2, 1) []
         i3 = call_loopinvariant(1, i1, descr=nonwritedescr)
         guard_no_exception() []
-        guard_value(i2, 1) []
+        guard_value(i3, 1) []
         i4 = call_loopinvariant(1, i1, descr=nonwritedescr)
         guard_no_exception() []
-        guard_value(i2, 1) []
+        guard_value(i4, 1) []
         jump(i1)
         """
         expected = """
@@ -1390,7 +1390,7 @@
         ops = """
         [p1]
         i1 = getfield_gc(p1, descr=valuedescr)
-        debug_merge_point(15)
+        debug_merge_point(15, 0)
         i2 = getfield_gc(p1, descr=valuedescr)
         escape(i1)
         escape(i2)
@@ -1399,7 +1399,7 @@
         expected = """
         [p1]
         i1 = getfield_gc(p1, descr=valuedescr)
-        debug_merge_point(15)
+        debug_merge_point(15, 0)
         escape(i1)
         escape(i1)
         jump(p1)

Modified: pypy/branch/fast-forward/pypy/jit/tl/pypyjit.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/tl/pypyjit.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/tl/pypyjit.py	Tue Nov  9 00:03:02 2010
@@ -38,13 +38,12 @@
 config.objspace.allworkingmodules = False
 config.objspace.usemodules.pypyjit = True
 config.objspace.usemodules.array = True
-config.objspace.usemodules._weakref = False
+config.objspace.usemodules._weakref = True
 config.objspace.usemodules._sre = False
 #
 config.objspace.usemodules._ffi = True
 #
 set_pypy_opt_level(config, level='jit')
-config.objspace.std.withinlineddict = True
 
 if BACKEND == 'c':
     config.objspace.std.multimethods = 'mrd'

Modified: pypy/branch/fast-forward/pypy/jit/tool/oparser.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/tool/oparser.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/tool/oparser.py	Tue Nov  9 00:03:02 2010
@@ -189,7 +189,7 @@
         descr = None
         if argspec.strip():
             if opname == 'debug_merge_point':
-                allargs = [argspec]
+                allargs = argspec.rsplit(', ', 1)
             else:
                 allargs = [arg for arg in argspec.split(",")
                            if arg != '']

Modified: pypy/branch/fast-forward/pypy/jit/tool/pypytrace.vim
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/tool/pypytrace.vim	(original)
+++ pypy/branch/fast-forward/pypy/jit/tool/pypytrace.vim	Tue Nov  9 00:03:02 2010
@@ -21,10 +21,10 @@
 
 hi def link pypyLoopStart   Structure
 "hi def link pypyLoopArgs    PreProc
-hi def link pypyFailArgs    String
-hi def link pypyOpName      Statement
-hi def link pypyDebugMergePoint  Comment
+hi def link pypyFailArgs    Special
+"hi def link pypyOpName      Statement
+hi def link pypyDebugMergePoint  String
 hi def link pypyConstPtr    Constant
 hi def link pypyNumber      Number
-hi def link pypyDescr       String
+hi def link pypyDescr       PreProc
 hi def link pypyDescrField  Label

Modified: pypy/branch/fast-forward/pypy/jit/tool/showstats.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/tool/showstats.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/tool/showstats.py	Tue Nov  9 00:03:02 2010
@@ -10,9 +10,10 @@
 
 def main(argv):
     log = logparser.parse_log_file(argv[0])
+    log_count_lines = open(argv[0] + '.count').readlines()
     parts = logparser.extract_category(log, "jit-log-opt-")
     for i, oplist in enumerate(parts):
-        loop = parse(oplist, no_namespace=True)
+        loop = parse(oplist, no_namespace=True, nonstrict=True)
         num_ops = 0
         num_dmp = 0
         num_guards = 0
@@ -23,7 +24,11 @@
                 num_ops += 1
             if op.is_guard():
                 num_guards += 1
-        print "Loop #%d, length: %d, opcodes: %d, guards: %d, %f" % (i, num_ops, num_dmp, num_guards, num_ops/num_dmp)
-
+        if num_dmp == 0:
+            print "Loop #%d, length: %d, opcodes: %d, guards: %d" % (i, num_ops, num_dmp, num_guards)
+        else:
+            print "Loop #%d, length: %d, opcodes: %d, guards: %d, %f" % (i, num_ops, num_dmp, num_guards, num_ops/num_dmp)
+        print loop.comment, "run", log_count_lines[i].split(":")[1].strip(), "times"
+        
 if __name__ == '__main__':
     main(sys.argv[1:])

Modified: pypy/branch/fast-forward/pypy/jit/tool/test/test_traceviewer.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/tool/test/test_traceviewer.py	(original)
+++ pypy/branch/fast-forward/pypy/jit/tool/test/test_traceviewer.py	Tue Nov  9 00:03:02 2010
@@ -19,7 +19,7 @@
     def test_no_of_loops(self):
         data = [preparse("""
         # Loop 0 : loop with 39 ops
-        debug_merge_point('')
+        debug_merge_point('', 0)
         guard_class(p4, 141310752, descr=<Guard5>) [p0, p1]
         p60 = getfield_gc(p4, descr=<GcPtrFieldDescr 16>)
         guard_nonnull(p60, descr=<Guard6>) [p0, p1]
@@ -51,7 +51,7 @@
         assert loop.right.content == 'extra'
 
     def test_postparse(self):
-        real_loops = [FinalBlock("debug_merge_point('<code object _runCallbacks, file '/tmp/x/twisted-trunk/twisted/internet/defer.py', line 357> #40 POP_TOP')", None)]
+        real_loops = [FinalBlock("debug_merge_point('<code object _runCallbacks, file '/tmp/x/twisted-trunk/twisted/internet/defer.py', line 357> #40 POP_TOP', 0)", None)]
         postprocess(real_loops, real_loops[:], {})
         assert real_loops[0].header.startswith("_runCallbacks, file '/tmp/x/twisted-trunk/twisted/internet/defer.py', line 357")
 

Modified: pypy/branch/fast-forward/pypy/module/__builtin__/descriptor.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/__builtin__/descriptor.py	(original)
+++ pypy/branch/fast-forward/pypy/module/__builtin__/descriptor.py	Tue Nov  9 00:03:02 2010
@@ -96,6 +96,8 @@
 )
 
 class W_Property(Wrappable):
+    _immutable_fields_ = ["w_fget", "w_fset", "w_fdel"]
+
     def init(self, space, w_fget=None, w_fset=None, w_fdel=None, w_doc=None):
         self.w_fget = w_fget
         self.w_fset = w_fset

Modified: pypy/branch/fast-forward/pypy/module/__builtin__/interp_classobj.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/__builtin__/interp_classobj.py	(original)
+++ pypy/branch/fast-forward/pypy/module/__builtin__/interp_classobj.py	Tue Nov  9 00:03:02 2010
@@ -411,8 +411,7 @@
         if w_meth is not None:
             space.call_function(w_meth, w_name, w_value)
         else:
-            # bit obscure: appease normalization
-            self.setdictvalue(space, name, w_value, True)
+            self.setdictvalue(space, name, w_value)
 
     def descr_delattr(self, space, w_name):
         name = unwrap_attr(space, w_name)

Modified: pypy/branch/fast-forward/pypy/module/__builtin__/test/test_classobj.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/__builtin__/test/test_classobj.py	(original)
+++ pypy/branch/fast-forward/pypy/module/__builtin__/test/test_classobj.py	Tue Nov  9 00:03:02 2010
@@ -981,28 +981,7 @@
         raises(TypeError, descr.__delete__, a)
 
 
-class AppTestOldStyleSharing(AppTestOldstyle):
-    def setup_class(cls):
-        cls.space = gettestobjspace(**{"objspace.std.withsharingdict": True})
-        if option.runappdirect:
-            py.test.skip("can only be run on py.py")
-        def is_sharing(space, w_inst):
-            from pypy.objspace.std.sharingdict import SharedDictImplementation
-            w_d = w_inst.getdict()
-            return space.wrap(isinstance(w_d, SharedDictImplementation) and w_d.r_dict_content is None)
-        cls.w_is_sharing = cls.space.wrap(gateway.interp2app(is_sharing))
-
-
-    def test_real_sharing(self):
-        class A:
-            def __init__(self):
-                self.x = 42
-        A1, A2, A3 = A(), A(), A()
-        assert self.is_sharing(A3)
-        assert self.is_sharing(A2)
-        assert self.is_sharing(A1)
-
-class AppTestOldStyleModDict(object):
+class AppTestOldStyleClassStrDict(object):
     def setup_class(cls):
         if option.runappdirect:
             py.test.skip("can only be run on py.py")

Modified: pypy/branch/fast-forward/pypy/module/__pypy__/__init__.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/__pypy__/__init__.py	(original)
+++ pypy/branch/fast-forward/pypy/module/__pypy__/__init__.py	Tue Nov  9 00:03:02 2010
@@ -25,3 +25,7 @@
                                  'interp_magic.reset_method_cache_counter')
         PYC_MAGIC = get_pyc_magic(self.space)
         self.extra_interpdef('PYC_MAGIC', 'space.wrap(%d)' % PYC_MAGIC)
+        #
+        from pypy.jit.backend import detect_cpu
+        model = detect_cpu.autodetect_main_model_and_size()
+        self.extra_interpdef('cpumodel', 'space.wrap(%r)' % model)

Modified: pypy/branch/fast-forward/pypy/module/__pypy__/test/test_special.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/__pypy__/test/test_special.py	(original)
+++ pypy/branch/fast-forward/pypy/module/__pypy__/test/test_special.py	Tue Nov  9 00:03:02 2010
@@ -17,3 +17,7 @@
         from __pypy__ import isfake
         import select
         assert isfake(select)
+
+    def test_cpumodel(self):
+        import __pypy__
+        assert hasattr(__pypy__, 'cpumodel')

Modified: pypy/branch/fast-forward/pypy/module/gc/interp_gc.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/gc/interp_gc.py	(original)
+++ pypy/branch/fast-forward/pypy/module/gc/interp_gc.py	Tue Nov  9 00:03:02 2010
@@ -5,6 +5,11 @@
 
 def collect(space):
     "Run a full collection."
+    # First clear the method cache.  See test_gc for an example of why.
+    if space.config.objspace.std.withmethodcache:
+        from pypy.objspace.std.typeobject import MethodCache
+        cache = space.fromcache(MethodCache)
+        cache.clear()
     rgc.collect()
     return space.wrap(0)
     

Modified: pypy/branch/fast-forward/pypy/module/gc/test/test_gc.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/gc/test/test_gc.py	(original)
+++ pypy/branch/fast-forward/pypy/module/gc/test/test_gc.py	Tue Nov  9 00:03:02 2010
@@ -103,3 +103,22 @@
         import gc
         gc.dump_heap_stats(self.fname)
 
+
+class AppTestGcMethodCache(object):
+    def setup_class(cls):
+        cls.space = gettestobjspace(**{"objspace.std.withmethodcache": True})
+
+    def test_clear_method_cache(self):
+        import gc, weakref
+        rlist = []
+        def f():
+            class C(object):
+                def f(self):
+                    pass
+            C().f()    # Fill the method cache
+            rlist.append(weakref.ref(C))
+        for i in range(5):
+            f()
+        gc.collect()    # the classes C should all go away here
+        for r in rlist:
+            assert r() is None

Modified: pypy/branch/fast-forward/pypy/module/pypyjit/interp_jit.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/pypyjit/interp_jit.py	(original)
+++ pypy/branch/fast-forward/pypy/module/pypyjit/interp_jit.py	Tue Nov  9 00:03:02 2010
@@ -6,6 +6,7 @@
 from pypy.tool.pairtype import extendabletype
 from pypy.rlib.rarithmetic import r_uint, intmask
 from pypy.rlib.jit import JitDriver, hint, we_are_jitted, dont_look_inside
+from pypy.rlib.jit import current_trace_length
 import pypy.interpreter.pyopcode   # for side-effects
 from pypy.interpreter.error import OperationError, operationerrfmt
 from pypy.interpreter.gateway import ObjSpace, Arguments, W_Root
@@ -80,9 +81,22 @@
 
     def jump_absolute(self, jumpto, _, ec=None):
         if we_are_jitted():
+            # Normally, the tick counter is decremented by 100 for every
+            # Python opcode.  Here, to better support JIT compilation of
+            # small loops, we decrement it by a possibly smaller constant.
+            # We get the maximum 100 when the (unoptimized) trace length
+            # is at least 3200 (a bit randomly).
+            trace_length = r_uint(current_trace_length())
+            decr_by = trace_length // 32
+            if decr_by < 1:
+                decr_by = 1
+            elif decr_by > 100:    # also if current_trace_length() returned -1
+                decr_by = 100
+            #
             self.last_instr = intmask(jumpto)
-            ec.bytecode_trace(self)
+            ec.bytecode_trace(self, intmask(decr_by))
             jumpto = r_uint(self.last_instr)
+        #
         pypyjitdriver.can_enter_jit(frame=self, ec=ec, next_instr=jumpto,
                                     pycode=self.getcode())
         return jumpto

Modified: pypy/branch/fast-forward/pypy/module/pypyjit/policy.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/pypyjit/policy.py	(original)
+++ pypy/branch/fast-forward/pypy/module/pypyjit/policy.py	Tue Nov  9 00:03:02 2010
@@ -6,7 +6,8 @@
         if (modname == '__builtin__.operation' or
                 modname == '__builtin__.abstractinst' or
                 modname == '__builtin__.interp_classobj' or
-                modname == '__builtin__.functional'):
+                modname == '__builtin__.functional' or
+                modname == '__builtin__.descriptor'):
             return True
         if '.' in modname:
             modname, _ = modname.split('.', 1)
@@ -19,7 +20,7 @@
         # this function should never actually return True directly
         # but instead call the base implementation
         mod = func.__module__ or '?'
-        
+
         if mod.startswith('pypy.objspace.'):
             # gc_id operation
             if func.__name__ == 'id__ANY':
@@ -36,5 +37,5 @@
             modname = mod[len('pypy.module.'):]
             if not self.look_inside_pypy_module(modname):
                 return False
-            
+
         return True

Modified: pypy/branch/fast-forward/pypy/module/pypyjit/test/test_policy.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/pypyjit/test/test_policy.py	(original)
+++ pypy/branch/fast-forward/pypy/module/pypyjit/test/test_policy.py	Tue Nov  9 00:03:02 2010
@@ -12,7 +12,7 @@
 
 def test_rlocale():
     from pypy.rlib.rlocale import setlocale
-    assert not pypypolicy.look_inside_function(setlocale)    
+    assert not pypypolicy.look_inside_function(setlocale)
 
 def test_geninterp():
     d = {'_geninterp_': True}
@@ -28,6 +28,10 @@
     from pypy.interpreter.pyparser import parser
     assert not pypypolicy.look_inside_function(parser.Grammar.__init__.im_func)
 
+def test_property():
+    from pypy.module.__builtin__.descriptor import W_Property
+    assert pypypolicy.look_inside_function(W_Property.get.im_func)
+
 def test_pypy_module():
     from pypy.module._random.interp_random import W_Random
     assert not pypypolicy.look_inside_function(W_Random.random)
@@ -35,6 +39,7 @@
     assert pypypolicy.look_inside_pypy_module('__builtin__.operation')
     assert pypypolicy.look_inside_pypy_module('__builtin__.abstractinst')
     assert pypypolicy.look_inside_pypy_module('__builtin__.functional')
+    assert pypypolicy.look_inside_pypy_module('__builtin__.descriptor')
     assert pypypolicy.look_inside_pypy_module('exceptions.interp_exceptions')
     for modname in 'pypyjit', 'signal', 'micronumpy', 'math', 'imp':
         assert pypypolicy.look_inside_pypy_module(modname)
@@ -42,4 +47,3 @@
 
 def test_see_jit_module():
     assert pypypolicy.look_inside_pypy_module('pypyjit.interp_jit')
-

Modified: pypy/branch/fast-forward/pypy/module/pypyjit/test/test_pypy_c.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/pypyjit/test/test_pypy_c.py	(original)
+++ pypy/branch/fast-forward/pypy/module/pypyjit/test/test_pypy_c.py	Tue Nov  9 00:03:02 2010
@@ -93,6 +93,9 @@
         # some support code...
         print >> f, py.code.Source("""
             import sys
+            # we don't want to see the small bridges created
+            # by the checkinterval reaching the limit
+            sys.setcheckinterval(10000000)
             try: # make the file runnable by CPython
                 import pypyjit
                 pypyjit.set_param(threshold=%d)
@@ -136,9 +139,10 @@
         assert opslogfile.check()
         log = logparser.parse_log_file(str(opslogfile))
         parts = logparser.extract_category(log, 'jit-log-opt-')
+        self.rawloops = [part for part in parts
+                         if not from_entry_bridge(part, parts)]
         # skip entry bridges, they can contain random things
-        self.loops = [parse(part, no_namespace=True) for part in parts
-                          if not from_entry_bridge(part, parts)]
+        self.loops = [parse(part, no_namespace=True) for part in self.rawloops]
         self.sliced_loops = [] # contains all bytecodes of all loops
         self.total_ops = 0
         for loop in self.loops:
@@ -162,12 +166,11 @@
         return [ops for ops in self.sliced_loops if ops.bytecode == name]
 
     def print_loops(self):
-        for loop in self.loops:
+        for rawloop in self.rawloops:
             print
             print '@' * 79
             print
-            for op in loop.operations:
-                print op
+            print rawloop.rstrip()
         print
         print '@' * 79
 
@@ -278,7 +281,7 @@
         assert len(ops) == 2
         assert not ops[0].get_opnames("call")
         assert not ops[0].get_opnames("new")
-        assert len(ops[0].get_opnames("guard")) <= 3     # we get 2 withmapdict
+        assert len(ops[0].get_opnames("guard")) <= 2
         assert not ops[1] # second LOOKUP_METHOD folded away
 
         ops = self.get_by_bytecode("CALL_METHOD")
@@ -294,7 +297,11 @@
 
         ops = self.get_by_bytecode("LOAD_ATTR")
         assert len(ops) == 2
-        assert ops[0].get_opnames() == ["getfield_gc", "getarrayitem_gc",
+        # With mapdict, we get fast access to (so far) the 5 first
+        # attributes, which means it is done with only the following
+        # operations.  (For the other attributes there is additionally
+        # a getarrayitem_gc.)
+        assert ops[0].get_opnames() == ["getfield_gc",
                                         "guard_nonnull_class"]
         assert not ops[1] # second LOAD_ATTR folded away
 
@@ -323,8 +330,8 @@
         assert len(ops) == 2
         assert not ops[0].get_opnames("call")
         assert not ops[0].get_opnames("new")
-        assert len(ops[0].get_opnames("guard")) <= 3    # we get 2 withmapdict
-        assert len(ops[0].get_opnames("getfield")) <= 5 # we get <5 withmapdict
+        assert len(ops[0].get_opnames("guard")) <= 2
+        assert len(ops[0].get_opnames("getfield")) <= 4
         assert not ops[1] # second LOOKUP_METHOD folded away
 
     def test_default_and_kw(self):

Modified: pypy/branch/fast-forward/pypy/module/signal/__init__.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/signal/__init__.py	(original)
+++ pypy/branch/fast-forward/pypy/module/signal/__init__.py	Tue Nov  9 00:03:02 2010
@@ -35,9 +35,7 @@
         MixedModule.__init__(self, space, *args)
         # add the signal-checking callback as an action on the space
         space.check_signal_action = interp_signal.CheckSignalAction(space)
-        space.actionflag.register_action(space.check_signal_action)
-        # use the C-level pypysig_occurred variable as the action flag
-        # (the result is that the C-level signal handler will directly
-        # set the flag for the CheckSignalAction)
+        space.actionflag.register_periodic_action(space.check_signal_action,
+                                                  use_bytecode_counter=False)
         space.actionflag.__class__ = interp_signal.SignalActionFlag
         # xxx yes I know the previous line is a hack

Modified: pypy/branch/fast-forward/pypy/module/signal/interp_signal.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/signal/interp_signal.py	(original)
+++ pypy/branch/fast-forward/pypy/module/signal/interp_signal.py	Tue Nov  9 00:03:02 2010
@@ -1,6 +1,7 @@
 from pypy.interpreter.error import OperationError
 from pypy.interpreter.baseobjspace import W_Root, ObjSpace
 from pypy.interpreter.executioncontext import AsyncAction, AbstractActionFlag
+from pypy.interpreter.executioncontext import PeriodicAsyncAction
 import signal as cpy_signal
 from pypy.rpython.lltypesystem import lltype, rffi
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
@@ -55,19 +56,29 @@
 
 
 class SignalActionFlag(AbstractActionFlag):
-    def get(self):
+    # This class uses the C-level pypysig_counter variable as the tick
+    # counter.  The C-level signal handler will reset it to -1 whenever
+    # a signal is received.
+
+    def get_ticker(self):
         p = pypysig_getaddr_occurred()
         return p.c_value
-    def set(self, value):
+
+    def reset_ticker(self, value):
         p = pypysig_getaddr_occurred()
         p.c_value = value
 
+    def decrement_ticker(self, by):
+        p = pypysig_getaddr_occurred()
+        value = p.c_value
+        if self.has_bytecode_counter:    # this 'if' is constant-folded
+            value -= by
+            p.c_value = value
+        return value
 
-class CheckSignalAction(AsyncAction):
-    """An action that is automatically invoked when a signal is received."""
 
-    # The C-level signal handler sets the bit 30 of pypysig_occurred:
-    bitmask = 1 << 30
+class CheckSignalAction(PeriodicAsyncAction):
+    """An action that is automatically invoked when a signal is received."""
 
     def __init__(self, space):
         AsyncAction.__init__(self, space)
@@ -76,7 +87,6 @@
             # need a helper action in case signals arrive in a non-main thread
             self.pending_signals = {}
             self.reissue_signal_action = ReissueSignalAction(space)
-            space.actionflag.register_action(self.reissue_signal_action)
         else:
             self.reissue_signal_action = None
 

Modified: pypy/branch/fast-forward/pypy/module/signal/test/test_signal.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/signal/test/test_signal.py	(original)
+++ pypy/branch/fast-forward/pypy/module/signal/test/test_signal.py	Tue Nov  9 00:03:02 2010
@@ -1,6 +1,38 @@
 import os, py
+import signal as cpy_signal
 from pypy.conftest import gettestobjspace
 
+
+class TestCheckSignals:
+
+    def setup_class(cls):
+        if not hasattr(os, 'kill') or not hasattr(os, 'getpid'):
+            py.test.skip("requires os.kill() and os.getpid()")
+        cls.space = gettestobjspace(usemodules=['signal'])
+
+    def test_checksignals(self):
+        space = self.space
+        w_received = space.appexec([], """():
+            import signal
+            received = []
+            def myhandler(signum, frame):
+                received.append(signum)
+            signal.signal(signal.SIGUSR1, myhandler)
+            return received""")
+        #
+        assert not space.is_true(w_received)
+        #
+        # send the signal now
+        os.kill(os.getpid(), cpy_signal.SIGUSR1)
+        #
+        # myhandler() should not be immediately called
+        assert not space.is_true(w_received)
+        #
+        # calling ec.checksignals() should call it
+        space.getexecutioncontext().checksignals()
+        assert space.is_true(w_received)
+
+
 class AppTestSignal:
 
     def setup_class(cls):
@@ -24,18 +56,12 @@
         signal.signal(signal.SIGUSR1, myhandler)
 
         posix.kill(posix.getpid(), signal.SIGUSR1)
-        for i in range(10000):
-             # wait a bit for the signal to be delivered to the handler
-            if received:
-                break
+        # the signal should be delivered to the handler immediately
         assert received == [signal.SIGUSR1]
         del received[:]
 
         posix.kill(posix.getpid(), signal.SIGUSR1)
-        for i in range(10000):
-             # wait a bit for the signal to be delivered to the handler
-            if received:
-                break
+        # the signal should be delivered to the handler immediately
         assert received == [signal.SIGUSR1]
         del received[:]
 

Modified: pypy/branch/fast-forward/pypy/module/sys/__init__.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/sys/__init__.py	(original)
+++ pypy/branch/fast-forward/pypy/module/sys/__init__.py	Tue Nov  9 00:03:02 2010
@@ -10,7 +10,6 @@
         if space.config.translating:
             del self.__class__.interpleveldefs['pypy_getudir']
         super(Module, self).__init__(space, w_name) 
-        self.checkinterval = 100
         self.recursionlimit = 100
         self.w_default_encoder = None
         self.defaultencoding = "ascii"

Modified: pypy/branch/fast-forward/pypy/module/sys/version.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/sys/version.py	(original)
+++ pypy/branch/fast-forward/pypy/module/sys/version.py	Tue Nov  9 00:03:02 2010
@@ -8,7 +8,7 @@
 CPYTHON_VERSION            = (2, 7, 0, "final", 42)   #XXX # sync patchlevel.h
 CPYTHON_API_VERSION        = 1012   #XXX # sync with include/modsupport.h
 
-PYPY_VERSION               = (1, 3, 0, "beta", '?')  #XXX # sync patchlevel.h
+PYPY_VERSION               = (1, 4, 0, "beta", '?')  #XXX # sync patchlevel.h
 # the last item is replaced by the svn revision ^^^
 
 TRIM_URL_UP_TO = 'svn/pypy/'

Modified: pypy/branch/fast-forward/pypy/module/sys/vm.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/sys/vm.py	(original)
+++ pypy/branch/fast-forward/pypy/module/sys/vm.py	Tue Nov  9 00:03:02 2010
@@ -67,7 +67,7 @@
 def setcheckinterval(space, interval):
     """Tell the Python interpreter to check for asynchronous events every
     n instructions.  This also affects how often thread switches occur."""
-    space.actionflag.setcheckinterval(space, interval)
+    space.actionflag.setcheckinterval(interval)
 setcheckinterval.unwrap_spec = [ObjSpace, int]
 
 def getcheckinterval(space):
@@ -77,7 +77,7 @@
     # return 0.  The idea is that according to the CPython docs, <= 0
     # means "check every virtual instruction, maximizing responsiveness
     # as well as overhead".
-    result = space.sys.checkinterval
+    result = space.actionflag.getcheckinterval()
     if result <= 1:
         result = 0
     return space.wrap(result)

Modified: pypy/branch/fast-forward/pypy/module/thread/gil.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/thread/gil.py	(original)
+++ pypy/branch/fast-forward/pypy/module/thread/gil.py	Tue Nov  9 00:03:02 2010
@@ -20,7 +20,8 @@
 
     def initialize(self, space):
         # add the GIL-releasing callback as an action on the space
-        space.actionflag.register_action(GILReleaseAction(space))
+        space.actionflag.register_periodic_action(GILReleaseAction(space),
+                                                  use_bytecode_counter=True)
 
     def setup_threads(self, space):
         """Enable threads in the object space, if they haven't already been."""
@@ -44,7 +45,6 @@
         # test_compile_lock.  As a workaround, we repatch these global
         # fields systematically.
         spacestate.ll_GIL = self.ll_GIL
-        spacestate.actionflag = space.actionflag
         invoke_around_extcall(before_external_call, after_external_call)
         return result
 
@@ -74,18 +74,17 @@
 
     def _freeze_(self):
         self.ll_GIL = thread.null_ll_lock
-        self.actionflag = None
-        self.set_actionflag_bit_after_thread_switch = 0
+        self.action_after_thread_switch = None
+        # ^^^ set by AsyncAction.fire_after_thread_switch()
         return False
 
     def after_thread_switch(self):
         # this is support logic for the signal module, to help it deliver
         # signals to the main thread.
-        actionflag = self.actionflag
-        if actionflag is not None:
-            flag = actionflag.get()
-            flag |= self.set_actionflag_bit_after_thread_switch
-            actionflag.set(flag)
+        action = self.action_after_thread_switch
+        if action is not None:
+            self.action_after_thread_switch = None
+            action.fire()
 
 spacestate = SpaceState()
 spacestate._freeze_()

Modified: pypy/branch/fast-forward/pypy/module/thread/test/test_gil.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/thread/test/test_gil.py	(original)
+++ pypy/branch/fast-forward/pypy/module/thread/test/test_gil.py	Tue Nov  9 00:03:02 2010
@@ -8,7 +8,7 @@
     pass
 
 class FakeActionFlag(object):
-    def register_action(self, action):
+    def register_periodic_action(self, action, use_bytecode_counter):
         pass
     def get(self):
         return 0

Modified: pypy/branch/fast-forward/pypy/objspace/descroperation.py
==============================================================================
--- pypy/branch/fast-forward/pypy/objspace/descroperation.py	(original)
+++ pypy/branch/fast-forward/pypy/objspace/descroperation.py	Tue Nov  9 00:03:02 2010
@@ -51,7 +51,7 @@
     return space.is_w(w_typ1, w_typ2)
 
 
-class Object:
+class Object(object):
     def descr__getattribute__(space, w_obj, w_name):
         name = space.str_w(w_name)
         w_descr = space.lookup(w_obj, name)
@@ -64,9 +64,7 @@
                     w_type = space.type(w_obj)
                     return space.get_and_call_function(w_get, w_descr, w_obj,
                                                        w_type)
-            w_value = w_obj.getdictvalue_attr_is_in_class(space, name)
-        else:
-            w_value = w_obj.getdictvalue(space, name)
+        w_value = w_obj.getdictvalue(space, name)
         if w_value is not None:
             return w_value
         if w_descr is not None:
@@ -76,13 +74,11 @@
     def descr__setattr__(space, w_obj, w_name, w_value):
         name = space.str_w(w_name)
         w_descr = space.lookup(w_obj, name)
-        shadows_type = False
         if w_descr is not None:
             if space.is_data_descr(w_descr):
                 space.set(w_descr, w_obj, w_value)
                 return
-            shadows_type = True
-        if w_obj.setdictvalue(space, name, w_value, shadows_type):
+        if w_obj.setdictvalue(space, name, w_value):
             return
         raiseattrerror(space, w_obj, name, w_descr)
 
@@ -100,7 +96,7 @@
     def descr__init__(space, w_obj, __args__):
         pass
 
-class DescrOperation:
+class DescrOperation(object):
     _mixin_ = True
 
     def is_data_descr(space, w_obj):
@@ -573,7 +569,7 @@
 
 # what is the maximum value slices can get on CPython?
 # we need to stick to that value, because fake.py etc.
-class Temp:
+class Temp(object):
     def __getslice__(self, i, j):
         return j
 slice_max = Temp()[:]

Modified: pypy/branch/fast-forward/pypy/objspace/std/callmethod.py
==============================================================================
--- pypy/branch/fast-forward/pypy/objspace/std/callmethod.py	(original)
+++ pypy/branch/fast-forward/pypy/objspace/std/callmethod.py	Tue Nov  9 00:03:02 2010
@@ -44,7 +44,7 @@
         else:
             typ = type(w_descr)
             if typ is function.Function or typ is function.FunctionWithFixedCode:
-                w_value = w_obj.getdictvalue_attr_is_in_class(space, name)
+                w_value = w_obj.getdictvalue(space, name)
                 if w_value is None:
                     # fast method path: a function object in the class,
                     # nothing in the instance
@@ -103,7 +103,7 @@
         w_descr = space.lookup(w_obj, methname)
         typ = type(w_descr)
         if typ is function.Function or typ is function.FunctionWithFixedCode:
-            w_value = w_obj.getdictvalue_attr_is_in_class(space, methname)
+            w_value = w_obj.getdictvalue(space, methname)
             if w_value is None:
                 # fast method path: a function object in the class,
                 # nothing in the instance

Modified: pypy/branch/fast-forward/pypy/objspace/std/celldict.py
==============================================================================
--- pypy/branch/fast-forward/pypy/objspace/std/celldict.py	(original)
+++ pypy/branch/fast-forward/pypy/objspace/std/celldict.py	Tue Nov  9 00:03:02 2010
@@ -47,7 +47,7 @@
         else:
             self._as_rdict().impl_fallback_setitem(w_key, w_value)
 
-    def impl_setitem_str(self, name, w_value, shadows_type=True):
+    def impl_setitem_str(self, name, w_value):
         self.getcell(name, True).w_value = w_value
 
     def impl_delitem(self, w_key):

Modified: pypy/branch/fast-forward/pypy/objspace/std/dictmultiobject.py
==============================================================================
--- pypy/branch/fast-forward/pypy/objspace/std/dictmultiobject.py	(original)
+++ pypy/branch/fast-forward/pypy/objspace/std/dictmultiobject.py	Tue Nov  9 00:03:02 2010
@@ -49,14 +49,6 @@
         elif space.config.objspace.std.withdictmeasurement:
             assert w_type is None
             return MeasuringDictImplementation(space)
-        elif space.config.objspace.std.withsharingdict and instance:
-            from pypy.objspace.std.sharingdict import SharedDictImplementation
-            assert w_type is None
-            return SharedDictImplementation(space)
-        elif (space.config.objspace.std.withshadowtracking and instance and
-                classofinstance is not None):
-            assert w_type is None
-            return ShadowDetectingDictImplementation(space, classofinstance)
         elif instance or strdict or module:
             assert w_type is None
             return StrDictImplementation(space)
@@ -112,7 +104,7 @@
         #return w_value or None
         raise NotImplementedError("abstract base class")
 
-    def impl_setitem_str(self, key, w_value, shadows_type=True):
+    def impl_setitem_str(self, key, w_value):
         raise NotImplementedError("abstract base class")
 
     def impl_setitem(self,  w_key, w_value):
@@ -165,12 +157,15 @@
         key = OPTIMIZED_BUILTINS[i]
         return self.impl_getitem_str(key)
 
-    # this method will only be seen whan a certain config option is used
-    def impl_shadows_anything(self):
-        return True
-
-    def impl_set_shadows_anything(self):
-        pass
+    def impl_popitem(self):
+        # default implementation
+        space = self.space
+        iterator = self.impl_iter()
+        w_key, w_value = iterator.next()
+        if w_key is None:
+            raise KeyError
+        self.impl_delitem(w_key)
+        return w_key, w_value
 
     # _________________________________________________________________
     # fallback implementation methods
@@ -178,7 +173,7 @@
     def impl_fallback_setitem(self, w_key, w_value):
         self.r_dict_content[w_key] = w_value
 
-    def impl_fallback_setitem_str(self, key, w_value, shadows_type=True):
+    def impl_fallback_setitem_str(self, key, w_value):
         return self.impl_fallback_setitem(self.space.wrap(key), w_value)
 
     def impl_fallback_delitem(self, w_key):
@@ -211,18 +206,15 @@
         key = OPTIMIZED_BUILTINS[i]
         return self.impl_fallback_getitem_str(key)
 
-    def impl_fallback_shadows_anything(self):
-        return True
-
-    def impl_fallback_set_shadows_anything(self):
-        pass
+    def impl_fallback_popitem(self):
+        return self.r_dict_content.popitem()
 
 
 implementation_methods = [
     ("getitem", 1),
     ("getitem_str", 1),
     ("length", 0),
-    ("setitem_str", 3),
+    ("setitem_str", 2),
     ("setitem", 2),
     ("delitem", 1),
     ("iter", 0),
@@ -231,8 +223,7 @@
     ("keys", 0),
     ("clear", 0),
     ("get_builtin_indexed", 1),
-    ("shadows_anything", 0),
-    ("set_shadows_anything", 0),
+    ("popitem", 0),
 ]
 
 
@@ -312,7 +303,7 @@
         else:
             self._as_rdict().impl_fallback_setitem(w_key, w_value)
 
-    def impl_setitem_str(self, key, w_value, shadows_type=True):
+    def impl_setitem_str(self, key, w_value):
         self.content[key] = w_value
 
     def impl_delitem(self, w_key):
@@ -388,47 +379,12 @@
             return None, None
 
 
-class ShadowDetectingDictImplementation(StrDictImplementation):
-    def __init__(self, space, w_type):
-        StrDictImplementation.__init__(self, space)
-        self.w_type = w_type
-        self.original_version_tag = w_type.version_tag()
-        if self.original_version_tag is None:
-            self._shadows_anything = True
-        else:
-            self._shadows_anything = False
-
-    def impl_setitem_str(self, key, w_value, shadows_type=True):
-        if shadows_type:
-            self._shadows_anything = True
-        StrDictImplementation.impl_setitem_str(
-            self, key, w_value, shadows_type)
-
-    def impl_setitem(self, w_key, w_value):
-        space = self.space
-        if space.is_w(space.type(w_key), space.w_str):
-            if not self._shadows_anything:
-                w_obj = self.w_type.lookup(space.str_w(w_key))
-                if w_obj is not None:
-                    self._shadows_anything = True
-            StrDictImplementation.impl_setitem_str(
-                self, self.space.str_w(w_key), w_value, False)
-        else:
-            self._as_rdict().impl_fallback_setitem(w_key, w_value)
-
-    def impl_shadows_anything(self):
-        return (self._shadows_anything or 
-                self.w_type.version_tag() is not self.original_version_tag)
-
-    def impl_set_shadows_anything(self):
-        self._shadows_anything = True
-
 class WaryDictImplementation(StrDictImplementation):
     def __init__(self, space):
         StrDictImplementation.__init__(self, space)
         self.shadowed = [None] * len(BUILTIN_TO_INDEX)
 
-    def impl_setitem_str(self, key, w_value, shadows_type=True):
+    def impl_setitem_str(self, key, w_value):
         i = BUILTIN_TO_INDEX.get(key, -1)
         if i != -1:
             self.shadowed[i] = w_value
@@ -558,7 +514,7 @@
         self.info.writes += 1
         self.content[w_key] = w_value
         self.info.maxcontents = max(self.info.maxcontents, len(self.content))
-    def impl_setitem_str(self, key, w_value, shadows_type=True):
+    def impl_setitem_str(self, key, w_value):
         self.info.setitem_strs += 1
         self.impl_setitem(self.space.wrap(key), w_value)
     def impl_delitem(self, w_key):
@@ -837,16 +793,11 @@
         return w_item
 
 def dict_popitem__DictMulti(space, w_dict):
-    # XXX should somehow use the same trick as CPython: saving the index
-    # of the last popped item in the hash table, so that the next call to
-    # popitem() can be more efficient, instead of always starting from the
-    # beginning of the hash table.
-    iterator = w_dict.iter()
-    w_key, w_value = iterator.next()
-    if w_key is None:
+    try:
+        w_key, w_value = w_dict.popitem()
+    except KeyError:
         raise OperationError(space.w_KeyError,
                              space.wrap("popitem(): dictionary is empty"))
-    w_dict.delitem(w_key)
     return space.newtuple([w_key, w_value])
 
 app = gateway.applevel('''

Modified: pypy/branch/fast-forward/pypy/objspace/std/inttype.py
==============================================================================
--- pypy/branch/fast-forward/pypy/objspace/std/inttype.py	(original)
+++ pypy/branch/fast-forward/pypy/objspace/std/inttype.py	Tue Nov  9 00:03:02 2010
@@ -2,7 +2,7 @@
 from pypy.interpreter.error import OperationError
 from pypy.objspace.std.register_all import register_all
 from pypy.objspace.std.stdtypedef import StdTypeDef, SMM
-from pypy.objspace.std.strutil import (string_to_int, string_to_w_long,
+from pypy.objspace.std.strutil import (string_to_int, string_to_bigint,
                                        ParseStringError,
                                        ParseStringOverflowError)
 from pypy.rlib.rarithmetic import r_uint
@@ -65,10 +65,12 @@
 def retry_to_w_long(space, parser, base=0):
     parser.rewind()
     try:
-        return string_to_w_long(space, None, base=base, parser=parser)
+        bigint = string_to_bigint(None, base=base, parser=parser)
     except ParseStringError, e:
         raise OperationError(space.w_ValueError,
                              space.wrap(e.msg))
+    from pypy.objspace.std.longobject import W_LongObject
+    return W_LongObject(bigint)
 
 def descr__new__(space, w_inttype, w_x=0, w_base=gateway.NoneNotWrapped):
     from pypy.objspace.std.intobject import W_IntObject

Modified: pypy/branch/fast-forward/pypy/objspace/std/listobject.py
==============================================================================
--- pypy/branch/fast-forward/pypy/objspace/std/listobject.py	(original)
+++ pypy/branch/fast-forward/pypy/objspace/std/listobject.py	Tue Nov  9 00:03:02 2010
@@ -283,7 +283,7 @@
         elif start >= 0:
             del items[start:start+delta]
         else:
-            assert delta==0
+            assert delta==0   # start<0 is only possible with slicelength==0
     elif len2 != slicelength:  # No resize for extended slices
         raise operationerrfmt(space.w_ValueError, "attempt to "
               "assign sequence of size %d to extended slice of size %d",

Modified: pypy/branch/fast-forward/pypy/objspace/std/longtype.py
==============================================================================
--- pypy/branch/fast-forward/pypy/objspace/std/longtype.py	(original)
+++ pypy/branch/fast-forward/pypy/objspace/std/longtype.py	Tue Nov  9 00:03:02 2010
@@ -2,7 +2,7 @@
 from pypy.interpreter import gateway, typedef
 from pypy.objspace.std.register_all import register_all
 from pypy.objspace.std.stdtypedef import StdTypeDef, SMM
-from pypy.objspace.std.strutil import string_to_w_long, ParseStringError
+from pypy.objspace.std.strutil import string_to_bigint, ParseStringError
 
 long_conjugate = SMM("conjugate", 1, doc="Returns self, the complex conjugate of any long.")
 
@@ -18,10 +18,10 @@
     if w_base is None:
         # check for easy cases
         if type(w_value) is W_LongObject:
-            pass
+            bigint = w_value.num
         elif space.is_true(space.isinstance(w_value, space.w_str)):
             try:
-                w_value = string_to_w_long(space, space.str_w(w_value))
+                bigint = string_to_bigint(space.str_w(w_value))
             except ParseStringError, e:
                 raise OperationError(space.w_ValueError,
                                      space.wrap(e.msg))
@@ -31,7 +31,7 @@
                     from pypy.objspace.std.ropeunicodeobject import unicode_to_decimal_w
                 else:
                     from pypy.objspace.std.unicodeobject import unicode_to_decimal_w
-                w_value = string_to_w_long(space, unicode_to_decimal_w(space, w_value))
+                bigint = string_to_bigint(unicode_to_decimal_w(space, w_value))
             except ParseStringError, e:
                 raise OperationError(space.w_ValueError,
                                      space.wrap(e.msg))
@@ -49,10 +49,11 @@
             if space.is_true(space.isinstance(w_obj, space.w_long)):
                 assert isinstance(w_obj, W_LongObject)  # XXX this could fail!
                 # XXX find a way to do that even if w_obj is not a W_LongObject
-                w_value = w_obj
+                bigint = w_obj.num
             elif space.is_true(space.isinstance(w_obj, space.w_int)):
+                from pypy.rlib.rbigint import rbigint
                 intval = space.int_w(w_obj)
-                w_value = W_LongObject.fromint(space, intval)
+                bigint = rbigint.fromint(intval)
             else:
                 raise OperationError(space.w_ValueError,
                                     space.wrap("value can't be converted to long"))
@@ -70,13 +71,13 @@
                                      space.wrap("long() can't convert non-string "
                                                 "with explicit base"))
         try:
-            w_value = string_to_w_long(space, s, base)
+            bigint = string_to_bigint(s, base)
         except ParseStringError, e:
             raise OperationError(space.w_ValueError,
                                  space.wrap(e.msg))
 
     w_obj = space.allocate_instance(W_LongObject, w_longtype)
-    W_LongObject.__init__(w_obj, w_value.num)
+    W_LongObject.__init__(w_obj, bigint)
     return w_obj
 
 def descr_get_numerator(space, w_obj):

Modified: pypy/branch/fast-forward/pypy/objspace/std/mapdict.py
==============================================================================
--- pypy/branch/fast-forward/pypy/objspace/std/mapdict.py	(original)
+++ pypy/branch/fast-forward/pypy/objspace/std/mapdict.py	Tue Nov  9 00:03:02 2010
@@ -1,4 +1,4 @@
-from pypy.rlib import jit, objectmodel
+from pypy.rlib import jit, objectmodel, debug
 
 from pypy.interpreter.baseobjspace import W_Root
 from pypy.objspace.std.dictmultiobject import W_DictMultiObject
@@ -10,6 +10,9 @@
 # attribute shapes
 
 NUM_DIGITS = 4
+NUM_DIGITS_POW2 = 1 << NUM_DIGITS
+# note: we use "x * NUM_DIGITS_POW2" instead of "x << NUM_DIGITS" because
+# we want to propagate knowledge that the result cannot be negative
 
 class AbstractAttribute(object):
     _immutable_fields_ = ['w_cls']
@@ -69,8 +72,10 @@
         attr = self._get_new_attr(selector[0], selector[1])
         oldattr = obj._get_mapdict_map()
         if not jit.we_are_jitted():
-            oldattr._size_estimate += attr.size_estimate() - oldattr.size_estimate()
-            assert oldattr.size_estimate() >= oldattr.length()
+            size_est = (oldattr._size_estimate + attr.size_estimate()
+                                               - oldattr.size_estimate())
+            assert size_est >= (oldattr.length() * NUM_DIGITS_POW2)
+            oldattr._size_estimate = size_est
         if attr.length() > obj._mapdict_storage_length():
             # note that attr.size_estimate() is always at least attr.length()
             new_storage = [None] * attr.size_estimate()
@@ -188,7 +193,7 @@
         self.selector = selector
         self.position = back.length()
         self.back = back
-        self._size_estimate = self.length() << NUM_DIGITS
+        self._size_estimate = self.length() * NUM_DIGITS_POW2
 
     def _copy_attr(self, obj, new_obj):
         w_value = self.read(obj, self.selector)
@@ -291,7 +296,7 @@
     def getdictvalue(self, space, attrname):
         return self._get_mapdict_map().read(self, (attrname, DICT))
 
-    def setdictvalue(self, space, attrname, w_value, shadows_type=True):
+    def setdictvalue(self, space, attrname, w_value):
         return self._get_mapdict_map().write(self, (attrname, DICT), w_value)
 
     def deldictvalue(self, space, w_name):
@@ -356,7 +361,8 @@
 
     def setweakref(self, space, weakreflifeline):
         from pypy.module._weakref.interp__weakref import WeakrefLifeline
-        assert isinstance(weakreflifeline, WeakrefLifeline)
+        assert (isinstance(weakreflifeline, WeakrefLifeline) or
+                    weakreflifeline is None)
         self._get_mapdict_map().write(self, ("weakref", SPECIAL), weakreflifeline)
 
 class ObjectMixin(object):
@@ -383,16 +389,18 @@
     assert space.config.objspace.std.withmapdict
     map = w_type.terminator
     classes = memo_get_subclass_of_correct_size(space, cls)
+    if SUBCLASSES_MIN_FIELDS == SUBCLASSES_MAX_FIELDS:
+        return classes[0]
     size = map.size_estimate()
-    if not size:
-        size = 1
-    try:
-        return classes[size - 1]
-    except IndexError:
-        return classes[-1]
+    debug.check_nonneg(size)
+    if size < len(classes):
+        return classes[size]
+    else:
+        return classes[len(classes)-1]
 get_subclass_of_correct_size._annspecialcase_ = "specialize:arg(1)"
 
-NUM_SUBCLASSES = 10 # XXX tweak this number
+SUBCLASSES_MIN_FIELDS = 5 # XXX tweak these numbers
+SUBCLASSES_MAX_FIELDS = 5
 
 def memo_get_subclass_of_correct_size(space, supercls):
     key = space, supercls
@@ -401,8 +409,12 @@
     except KeyError:
         assert not hasattr(supercls, "__del__")
         result = []
-        for i in range(1, NUM_SUBCLASSES+1):
+        for i in range(SUBCLASSES_MIN_FIELDS, SUBCLASSES_MAX_FIELDS+1):
             result.append(_make_subclass_size_n(supercls, i))
+        for i in range(SUBCLASSES_MIN_FIELDS):
+            result.insert(0, result[0])
+        if SUBCLASSES_MIN_FIELDS == SUBCLASSES_MAX_FIELDS:
+            assert len(set(result)) == 1
         _subclass_cache[key] = result
         return result
 memo_get_subclass_of_correct_size._annspecialcase_ = "specialize:memo"
@@ -413,7 +425,7 @@
     rangen = unroll.unrolling_iterable(range(n))
     nmin1 = n - 1
     rangenmin1 = unroll.unrolling_iterable(range(nmin1))
-    class subcls(ObjectMixin, BaseMapdictObject, supercls):
+    class subcls(BaseMapdictObject, supercls):
         def _init_empty(self, map):
             from pypy.rlib.debug import make_sure_not_resized
             for i in rangen:
@@ -506,8 +518,8 @@
     def impl_getitem_str(self, key):
         return self.w_obj.getdictvalue(self.space, key)
 
-    def impl_setitem_str(self,  key, w_value, shadows_type=True):
-        flag = self.w_obj.setdictvalue(self.space, key, w_value, shadows_type)
+    def impl_setitem_str(self,  key, w_value):
+        flag = self.w_obj.setdictvalue(self.space, key, w_value)
         assert flag
 
     def impl_setitem(self,  w_key, w_value):
@@ -588,8 +600,6 @@
 # ____________________________________________________________
 # Magic caching
 
-# XXX we also would like getdictvalue_attr_is_in_class() above
-
 class CacheEntry(object):
     map = None
     version_tag = None

Modified: pypy/branch/fast-forward/pypy/objspace/std/objspace.py
==============================================================================
--- pypy/branch/fast-forward/pypy/objspace/std/objspace.py	(original)
+++ pypy/branch/fast-forward/pypy/objspace/std/objspace.py	Tue Nov  9 00:03:02 2010
@@ -437,7 +437,7 @@
             if is_data:
                 w_get = self.lookup(w_descr, "__get__")
             if w_get is None:
-                w_value = w_obj.getdictvalue_attr_is_in_class(self, name)
+                w_value = w_obj.getdictvalue(self, name)
                 if w_value is not None:
                     return w_value
                 if not is_data:
@@ -489,14 +489,12 @@
             return w_obj.getitem(w_key)
         return ObjSpace.finditem(self, w_obj, w_key)
 
-    def setitem_str(self, w_obj, key, w_value, shadows_type=True):
+    def setitem_str(self, w_obj, key, w_value):
         """ Same as setitem, but takes string instead of any wrapped object
-
-        XXX what shadows_type means???
         """
         if (isinstance(w_obj, W_DictMultiObject) and
                 not w_obj.user_overridden_class):
-            w_obj.setitem_str(key, w_value, shadows_type)
+            w_obj.setitem_str(key, w_value)
         else:
             self.setitem(w_obj, self.wrap(key), w_value)
 

Modified: pypy/branch/fast-forward/pypy/objspace/std/proxyobject.py
==============================================================================
--- pypy/branch/fast-forward/pypy/objspace/std/proxyobject.py	(original)
+++ pypy/branch/fast-forward/pypy/objspace/std/proxyobject.py	Tue Nov  9 00:03:02 2010
@@ -43,7 +43,7 @@
                     raise
                 return None
         
-        def setdictvalue(self, space, attr, w_value, shadows_type=True):
+        def setdictvalue(self, space, attr, w_value):
             try:
                 space.call_function(self.w_controller, space.wrap('__setattr__'),
                    space.wrap(attr), w_value)

Modified: pypy/branch/fast-forward/pypy/objspace/std/smallintobject.py
==============================================================================
--- pypy/branch/fast-forward/pypy/objspace/std/smallintobject.py	(original)
+++ pypy/branch/fast-forward/pypy/objspace/std/smallintobject.py	Tue Nov  9 00:03:02 2010
@@ -2,18 +2,13 @@
 Implementation of small ints, stored as odd-valued pointers in the
 translated PyPy.  To enable them, see inttype.py.
 """
-import types
-from pypy.interpreter.error import OperationError
 from pypy.objspace.std import intobject
 from pypy.objspace.std.model import registerimplementation, W_Object
 from pypy.objspace.std.register_all import register_all
-from pypy.objspace.std.multimethod import FailedToImplementArgs
 from pypy.objspace.std.noneobject import W_NoneObject
-from pypy.rlib.rarithmetic import ovfcheck, ovfcheck_lshift, LONG_BIT, r_uint
-from pypy.objspace.std.inttype import wrapint
-from pypy.objspace.std.intobject import W_IntObject, _impl_int_int_pow
+from pypy.objspace.std.intobject import W_IntObject
 from pypy.rlib.objectmodel import UnboxedValue
-from pypy.rlib.rbigint import rbigint
+from pypy.tool.sourcetools import func_with_new_name
 
 
 class W_SmallIntObject(W_Object, UnboxedValue):
@@ -46,9 +41,7 @@
             new_name = name.replace("Int", "SmallInt")
             # Copy the function, so the annotator specializes it for
             # W_SmallIntObject.
-            ns[new_name] = types.FunctionType(func.func_code, ns, new_name,
-                                              func.func_defaults,
-                                              func.func_closure)
+            ns[new_name] = func_with_new_name(func, new_name)
     ns["get_integer"] = ns["pos__SmallInt"] = ns["int__SmallInt"]
     ns["get_negint"] = ns["neg__SmallInt"]
 

Modified: pypy/branch/fast-forward/pypy/objspace/std/stringobject.py
==============================================================================
--- pypy/branch/fast-forward/pypy/objspace/std/stringobject.py	(original)
+++ pypy/branch/fast-forward/pypy/objspace/std/stringobject.py	Tue Nov  9 00:03:02 2010
@@ -942,10 +942,17 @@
 
     string = w_string._value
     chars = []
-    for char in string:
-        w_char = W_StringObject.PREBUILT[ord(char)]
-        if not space.is_true(space.contains(w_deletechars, w_char)):
-             chars.append(table[ord(char)])
+    deletechars = space.str_w(w_deletechars)
+    if len(deletechars) == 0:
+        for char in string:
+            chars.append(table[ord(char)])
+    else:
+        deletion_table = [False] * 256
+        for c in deletechars:
+            deletion_table[ord(c)] = True
+        for char in string:
+            if not deletion_table[ord(char)]:
+                chars.append(table[ord(char)])
     return W_StringObject(''.join(chars))
 
 def str_decode__String_ANY_ANY(space, w_string, w_encoding=None, w_errors=None):

Modified: pypy/branch/fast-forward/pypy/objspace/std/strutil.py
==============================================================================
--- pypy/branch/fast-forward/pypy/objspace/std/strutil.py	(original)
+++ pypy/branch/fast-forward/pypy/objspace/std/strutil.py	Tue Nov  9 00:03:02 2010
@@ -4,6 +4,7 @@
 
 from pypy.rlib.rarithmetic import ovfcheck, break_up_float, parts_to_float,\
      INFINITY, NAN
+from pypy.rlib.rbigint import rbigint, parse_digit_string
 from pypy.interpreter.error import OperationError
 import math
 
@@ -97,9 +98,10 @@
             return -1
 
 def string_to_int(s, base=10):
-    """Utility to converts a string to an integer (or possibly a long).
+    """Utility to converts a string to an integer.
     If base is 0, the proper base is guessed based on the leading
     characters of 's'.  Raises ParseStringError in case of error.
+    Raises ParseStringOverflowError in case the result does not fit.
     """
     s = literal = strip_spaces(s)
     p = NumberStringParser(s, literal, base, 'int')
@@ -119,11 +121,9 @@
         except OverflowError:
             raise ParseStringOverflowError(p)
 
-def string_to_long(space, s, base=10, parser=None):
-    return string_to_w_long(space, s, base, parser).longval()
-
-def string_to_w_long(space, s, base=10, parser=None):
-    """As string_to_int(), but ignores an optional 'l' or 'L' suffix."""
+def string_to_bigint(s, base=10, parser=None):
+    """As string_to_int(), but ignores an optional 'l' or 'L' suffix
+    and returns an rbigint."""
     if parser is None:
         s = literal = strip_spaces(s)
         if (s.endswith('l') or s.endswith('L')) and base < 22:
@@ -132,18 +132,7 @@
         p = NumberStringParser(s, literal, base, 'long')
     else:
         p = parser
-    w_base = space.newlong(p.base)
-    w_result = space.newlong(0)
-    while True:
-        digit = p.next_digit()
-        if digit == -1:
-            if p.sign == -1:
-                w_result = space.neg(w_result)
-            # XXX grumble
-            from pypy.objspace.std.longobject import W_LongObject
-            assert isinstance(w_result, W_LongObject)
-            return w_result
-        w_result = space.add(space.mul(w_result,w_base), space.newlong(digit))
+    return parse_digit_string(p)
 
 # Tim's comment:
 # 57 bits are more than needed in any case.

Modified: pypy/branch/fast-forward/pypy/objspace/std/test/test_dictmultiobject.py
==============================================================================
--- pypy/branch/fast-forward/pypy/objspace/std/test/test_dictmultiobject.py	(original)
+++ pypy/branch/fast-forward/pypy/objspace/std/test/test_dictmultiobject.py	Tue Nov  9 00:03:02 2010
@@ -4,7 +4,6 @@
      StrDictImplementation
 
 from pypy.objspace.std.celldict import ModuleDictImplementation
-from pypy.objspace.std.sharingdict import SharedDictImplementation
 from pypy.conftest import gettestobjspace
 
 
@@ -239,7 +238,16 @@
         assert len(d) == 0
         assert (it!=it1) and (it1==(1,2) or it1==(3,4))
         raises(KeyError, d.popitem)
-    
+
+    def test_popitem_2(self):
+        class A(object):
+            pass
+        d = A().__dict__
+        d['x'] = 5
+        it1 = d.popitem()
+        assert it1 == ('x', 5)
+        raises(KeyError, d.popitem)
+
     def test_setdefault(self):
         d = {1:2, 3:4}
         dd = d.copy()
@@ -513,32 +521,6 @@
         assert getattr(a, s) == 42
 
 
-class TestW_DictSharing(TestW_DictObject):
-    def setup_class(cls):
-        cls.space = gettestobjspace(**{"objspace.std.withsharingdict": True})
-
-class AppTest_DictSharing(AppTest_DictObject):
-    def setup_class(cls):
-        cls.space = gettestobjspace(**{"objspace.std.withsharingdict": True})
-
-    def test_values_does_not_share(self):
-        class A(object):
-            pass
-        a = A()
-        a.abc = 12
-        l = a.__dict__.values()
-        assert l == [12]
-        l[0] = 24
-        assert a.abc == 12
-
-    def test_items(self):
-        class A(object):
-            pass
-        a = A()
-        a.abc = 12
-        a.__dict__.items() == [("abc", 12)]
-
-
 class AppTestModuleDict(object):
     def setup_class(cls):
         cls.space = gettestobjspace(**{"objspace.std.withcelldict": True})
@@ -632,10 +614,8 @@
     class objspace:
         class std:
             withdictmeasurement = False
-            withsharingdict = False
             withsmalldicts = False
             withcelldict = False
-            withshadowtracking = False
         class opcodes:
             CALL_LIKELY_BUILTIN = False
 
@@ -770,9 +750,6 @@
     string = "int"
     string2 = "isinstance"
 
-class TestSharedDictImplementation(BaseTestRDictImplementation):
-    ImplementionClass = SharedDictImplementation
-
 
 class BaseTestDevolvedDictImplementation(BaseTestRDictImplementation):
     def fill_impl(self):
@@ -794,8 +771,6 @@
     string = "int"
     string2 = "isinstance"
 
-class TestDevolvedSharedDictImplementation(BaseTestDevolvedDictImplementation):
-    ImplementionClass = SharedDictImplementation
 
 def test_module_uses_strdict():
     fakespace = FakeSpace()

Modified: pypy/branch/fast-forward/pypy/objspace/std/test/test_longobject.py
==============================================================================
--- pypy/branch/fast-forward/pypy/objspace/std/test/test_longobject.py	(original)
+++ pypy/branch/fast-forward/pypy/objspace/std/test/test_longobject.py	Tue Nov  9 00:03:02 2010
@@ -47,22 +47,28 @@
         assert math.trunc(-1L) == -1L
 
     def test_add(self):
-        assert int(123L + 12443L) == 123 + 12443
-        assert -20 + 2 + 3L + True == -14L
+        x = 123L
+        assert int(x + 12443L) == 123 + 12443
+        x = -20
+        assert x + 2 + 3L + True == -14L
 
     def test_sub(self):
-        assert int(58543L - 12332L) == 58543 - 12332
-        assert 237123838281233L * 12 == 237123838281233L * 12L
+        x = 58543L
+        assert int(x - 12332L) == 58543 - 12332
+        x = 237123838281233L
+        assert x * 12 == x * 12L
 
     def test_mul(self):
-        assert 363L * 2 ** 40 == 363L << 40
+        x = 363L
+        assert x * 2 ** 40 == x << 40
 
     def test_truediv(self):
         exec "from __future__ import division; a = 31415926L / 10000000L"
         assert a == 3.1415926
 
     def test_floordiv(self):
-        a = 31415926L // 10000000L
+        x = 31415926L
+        a = x // 10000000L
         assert a == 3L
 
     def test_numerator_denominator(self):
@@ -72,37 +78,39 @@
         assert (42L).denominator == 1L
 
     def test_compare(self):
+        Z = 0
+        ZL = 0L
         for BIG in (1L, 1L << 62, 1L << 9999):
-            assert 0 == 0L
-            assert not (0 != 0L)
-            assert 0L == 0
-            assert not (0L != 0)
-            assert not (0 == BIG)
-            assert 0 != BIG
-            assert not (BIG == 0)
-            assert BIG != 0
-            assert not (0L == BIG)
-            assert 0L != BIG
-            assert 0 <= 0L
-            assert not (0 < 0L)
-            assert 0 <= BIG
-            assert 0 < BIG
-            assert not (BIG <= 0)
-            assert not (BIG < 0)
-            assert 0L <= 0L
-            assert not (0L < 0L)
-            assert 0L <= BIG
-            assert 0L < BIG
-            assert not (BIG <= 0L)
-            assert not (BIG < 0L)
-            assert not (0 <= -BIG)
-            assert not (0 < -BIG)
-            assert -BIG <= 0
-            assert -BIG < 0
-            assert not (0L <= -BIG)
-            assert not (0L < -BIG)
-            assert -BIG <= 0L
-            assert -BIG < 0L
+            assert Z == ZL
+            assert not (Z != ZL)
+            assert ZL == Z
+            assert not (ZL != Z)
+            assert not (Z == BIG)
+            assert Z != BIG
+            assert not (BIG == Z)
+            assert BIG != Z
+            assert not (ZL == BIG)
+            assert ZL != BIG
+            assert Z <= ZL
+            assert not (Z < ZL)
+            assert Z <= BIG
+            assert Z < BIG
+            assert not (BIG <= Z)
+            assert not (BIG < Z)
+            assert ZL <= ZL
+            assert not (ZL < ZL)
+            assert ZL <= BIG
+            assert ZL < BIG
+            assert not (BIG <= ZL)
+            assert not (BIG < ZL)
+            assert not (Z <= -BIG)
+            assert not (Z < -BIG)
+            assert -BIG <= Z
+            assert -BIG < Z
+            assert not (ZL <= -BIG)
+            assert not (ZL < -BIG)
+            assert -BIG <= ZL
+            assert -BIG < ZL
             #
             assert not (BIG <  int(BIG))
             assert     (BIG <= int(BIG))
@@ -149,7 +157,8 @@
     def test_conversion(self):
         class long2(long):
             pass
-        x = long2(1L<<100)
+        x = 1L
+        x = long2(x<<100)
         y = int(x)
         assert type(y) == long
         assert type(+long2(5)) is long
@@ -164,7 +173,8 @@
         assert type(long2(5) // 1) is long
 
     def test_pow(self):
-        assert pow(0L, 0L, 1L) == 0L
+        x = 0L
+        assert pow(x, 0L, 1L) == 0L
 
     def test_getnewargs(self):
         assert  0L .__getnewargs__() == (0L,)
@@ -205,13 +215,14 @@
         assert oct(01234567012345670L) == '01234567012345670L'
 
     def test_bits(self):
-        assert 0xAAAAAAAAL | 0x55555555L == 0xFFFFFFFFL
-        assert 0xAAAAAAAAL & 0x55555555L == 0x00000000L
-        assert 0xAAAAAAAAL ^ 0x55555555L == 0xFFFFFFFFL
-        assert -0xAAAAAAAAL | 0x55555555L == -0xAAAAAAA9L
-        assert 0xAAAAAAAAL | 0x555555555L == 0x5FFFFFFFFL
-        assert 0xAAAAAAAAL & 0x555555555L == 0x000000000L
-        assert 0xAAAAAAAAL ^ 0x555555555L == 0x5FFFFFFFFL
+        x = 0xAAAAAAAAL
+        assert x | 0x55555555L == 0xFFFFFFFFL
+        assert x & 0x55555555L == 0x00000000L
+        assert x ^ 0x55555555L == 0xFFFFFFFFL
+        assert -x | 0x55555555L == -0xAAAAAAA9L
+        assert x | 0x555555555L == 0x5FFFFFFFFL
+        assert x & 0x555555555L == 0x000000000L
+        assert x ^ 0x555555555L == 0x5FFFFFFFFL
 
     def test_hash(self):
         # ints have the same hash as equal longs
@@ -241,7 +252,8 @@
 
     def test_huge_longs(self):
         import operator
-        huge = 1L << 40000L
+        x = 1L
+        huge = x << 40000L
         raises(OverflowError, float, huge)
         raises(OverflowError, operator.truediv, huge, 3)
         raises(OverflowError, operator.truediv, huge, 3L)
@@ -260,17 +272,23 @@
         class myotherlong(long):
             pass
         assert long(myotherlong(21)) == 21L
-    
+
     def test_conjugate(self):
         assert (7L).conjugate() == 7L
         assert (-7L).conjugate() == -7L
-        
+
         class L(long):
             pass
-        
+
         assert type(L(7).conjugate()) is long
 
     def test_bit_length(self):
         assert 8L.bit_length() == 4
         assert (-1<<40).bit_length() == 41
         assert ((2**31)-1).bit_length() == 31
+
+
+    def test_negative_zero(self):
+        x = eval("-0L")
+        assert x == 0L
+

Modified: pypy/branch/fast-forward/pypy/objspace/std/test/test_mapdict.py
==============================================================================
--- pypy/branch/fast-forward/pypy/objspace/std/test/test_mapdict.py	(original)
+++ pypy/branch/fast-forward/pypy/objspace/std/test/test_mapdict.py	Tue Nov  9 00:03:02 2010
@@ -160,6 +160,13 @@
     assert obj.getweakref() is lifeline1
     assert obj.getdictvalue(space, "weakref") == 41
 
+    lifeline1 = WeakrefLifeline(space)
+    obj = c.instantiate()
+    assert obj.getweakref() is None
+    obj.setweakref(space, lifeline1)
+    obj.setweakref(space, None)
+
+
 
 def test_slots():
     cls = Class()
@@ -777,3 +784,19 @@
         assert res == (0, 0, 1)
         res = self.check(f, 'x')
         assert res == (0, 0, 1)
+
+class TestDictSubclassShortcutBug(object):
+    def setup_class(cls):
+        cls.space = gettestobjspace(
+            **{"objspace.std.withmapdict": True,
+               "objspace.std.withmethodcachecounter": True})
+
+    def test_bug(self):
+        w_dict = self.space.appexec([], """():
+                class A(dict):
+                    def __getitem__(self, key):
+                        return 1
+                assert eval("a", globals(), A()) == 1
+                return A()
+                """)
+        assert w_dict.user_overridden_class

Modified: pypy/branch/fast-forward/pypy/objspace/std/test/test_strutil.py
==============================================================================
--- pypy/branch/fast-forward/pypy/objspace/std/test/test_strutil.py	(original)
+++ pypy/branch/fast-forward/pypy/objspace/std/test/test_strutil.py	Tue Nov  9 00:03:02 2010
@@ -25,7 +25,7 @@
                  ]
         for s, expected in cases:
             assert string_to_int(s) == expected
-            assert string_to_w_long(space, s).longval() == expected
+            assert string_to_bigint(s).tolong() == expected
 
     def test_string_to_int_base(self):
         space = self.space        
@@ -122,17 +122,16 @@
             raises(ParseStringError, string_to_int, '+'+s, base)
             raises(ParseStringError, string_to_int, '-'+s, base)
 
-    def test_string_to_w_long(self):
-        space = self.space
-        assert string_to_w_long(space, '123L').longval() == 123
-        assert string_to_w_long(space, '123L  ').longval() == 123
-        raises(ParseStringError, string_to_w_long, space, 'L')
-        raises(ParseStringError, string_to_w_long, space, 'L  ')
-        assert string_to_w_long(space, '123L', 4).longval() == 27
-        assert string_to_w_long(space, '123L', 30).longval() == 27000 + 1800 + 90 + 21
-        assert string_to_w_long(space, '123L', 22).longval() == 10648 + 968 + 66 + 21
-        assert string_to_w_long(space, '123L', 21).longval() == 441 + 42 + 3
-        assert string_to_w_long(space, '1891234174197319').longval() == 1891234174197319
+    def test_string_to_bigint(self):
+        assert string_to_bigint('123L').tolong() == 123
+        assert string_to_bigint('123L  ').tolong() == 123
+        raises(ParseStringError, string_to_bigint, 'L')
+        raises(ParseStringError, string_to_bigint, 'L  ')
+        assert string_to_bigint('123L', 4).tolong() == 27
+        assert string_to_bigint('123L', 30).tolong() == 27000 + 1800 + 90 + 21
+        assert string_to_bigint('123L', 22).tolong() == 10648 + 968 + 66 + 21
+        assert string_to_bigint('123L', 21).tolong() == 441 + 42 + 3
+        assert string_to_bigint('1891234174197319').tolong() == 1891234174197319
 
     def test_string_to_float(self):
         def string_to_float(x):

Modified: pypy/branch/fast-forward/pypy/objspace/std/typeobject.py
==============================================================================
--- pypy/branch/fast-forward/pypy/objspace/std/typeobject.py	(original)
+++ pypy/branch/fast-forward/pypy/objspace/std/typeobject.py	Tue Nov  9 00:03:02 2010
@@ -61,6 +61,15 @@
             self.hits = {}
             self.misses = {}
 
+    def clear(self):
+        None_None = (None, None)
+        for i in range(len(self.versions)):
+            self.versions[i] = None
+        for i in range(len(self.names)):
+            self.names[i] = None
+        for i in range(len(self.lookup_where)):
+            self.lookup_where[i] = None_None
+
 
 class W_TypeObject(W_Object):
     from pypy.objspace.std.typetype import type_typedef as typedef

Modified: pypy/branch/fast-forward/pypy/rlib/jit.py
==============================================================================
--- pypy/branch/fast-forward/pypy/rlib/jit.py	(original)
+++ pypy/branch/fast-forward/pypy/rlib/jit.py	Tue Nov  9 00:03:02 2010
@@ -4,6 +4,7 @@
 from pypy.rlib.objectmodel import CDefinedIntSymbolic
 from pypy.rlib.objectmodel import keepalive_until_here
 from pypy.rlib.unroll import unrolling_iterable
+from pypy.rlib.nonconst import NonConstant
 
 def purefunction(func):
     """ Decorate a function as pure. Pure means precisely that:
@@ -145,6 +146,14 @@
         return hop.inputconst(lltype.Signed, _we_are_jitted)
 
 
+def current_trace_length():
+    """During JIT tracing, returns the current trace length (as a constant).
+    If not tracing, returns -1."""
+    if NonConstant(False):
+        return 73
+    return -1
+current_trace_length.oopspec = 'jit.current_trace_length()'
+
 def jit_debug(string, arg1=-sys.maxint-1, arg2=-sys.maxint-1,
                       arg3=-sys.maxint-1, arg4=-sys.maxint-1):
     """When JITted, cause an extra operation DEBUG_MERGE_POINT to appear in

Modified: pypy/branch/fast-forward/pypy/rlib/objectmodel.py
==============================================================================
--- pypy/branch/fast-forward/pypy/rlib/objectmodel.py	(original)
+++ pypy/branch/fast-forward/pypy/rlib/objectmodel.py	Tue Nov  9 00:03:02 2010
@@ -475,6 +475,10 @@
     def setdefault(self, key, default):
         return self._dict.setdefault(_r_dictkey(self, key), default)
 
+    def popitem(self):
+        dk, value = self._dict.popitem()
+        return dk.key, value
+
     def copy(self):
         result = r_dict(self.key_eq, self.key_hash)
         result.update(self)

Modified: pypy/branch/fast-forward/pypy/rlib/rbigint.py
==============================================================================
--- pypy/branch/fast-forward/pypy/rlib/rbigint.py	(original)
+++ pypy/branch/fast-forward/pypy/rlib/rbigint.py	Tue Nov  9 00:03:02 2010
@@ -1610,11 +1610,16 @@
 
 # a few internal helpers
 
-DEC_PER_DIGIT = 1
-while int('9' * DEC_PER_DIGIT) < MASK:
-    DEC_PER_DIGIT += 1
-DEC_PER_DIGIT -= 1
-DEC_MAX = 10 ** DEC_PER_DIGIT
+def digits_max_for_base(base):
+    dec_per_digit = 1
+    while base ** dec_per_digit < MASK:
+        dec_per_digit += 1
+    dec_per_digit -= 1
+    return base ** dec_per_digit
+
+BASE_MAX = [0, 0] + [digits_max_for_base(_base) for _base in range(2, 37)]
+DEC_MAX = digits_max_for_base(10)
+assert DEC_MAX == BASE_MAX[10]
 
 def _decimalstr_to_bigint(s):
     # a string that has been already parsed to be decimal and valid,
@@ -1629,7 +1634,6 @@
         p += 1
 
     a = rbigint.fromint(0)
-    cnt = DEC_PER_DIGIT
     tens = 1
     dig = 0
     ord0 = ord('0')
@@ -1641,8 +1645,26 @@
             a = _muladd1(a, tens, dig)
             tens = 1
             dig = 0
-    if sign:
+    if sign and a.sign == 1:
         a.sign = -1
     return a
 
-
+def parse_digit_string(parser):
+    # helper for objspace.std.strutil
+    a = rbigint.fromint(0)
+    base = parser.base
+    digitmax = BASE_MAX[base]
+    tens, dig = 1, 0
+    while True:
+        digit = parser.next_digit()
+        if tens == digitmax or digit < 0:
+            a = _muladd1(a, tens, dig)
+            if digit < 0:
+                break
+            dig = digit
+            tens = base
+        else:
+            dig = dig * base + digit
+            tens *= base
+    a.sign *= parser.sign
+    return a

Modified: pypy/branch/fast-forward/pypy/rlib/test/test_rbigint.py
==============================================================================
--- pypy/branch/fast-forward/pypy/rlib/test/test_rbigint.py	(original)
+++ pypy/branch/fast-forward/pypy/rlib/test/test_rbigint.py	Tue Nov  9 00:03:02 2010
@@ -112,6 +112,23 @@
         assert rbigint.fromrarith_int(r_uint(2*sys.maxint+1)).eq(
             rbigint.fromlong(2*sys.maxint+1))
 
+    def test_fromdecimalstr(self):
+        x = rbigint.fromdecimalstr("12345678901234567890523897987")
+        assert x.tolong() == 12345678901234567890523897987L
+        assert x.tobool() is True
+        x = rbigint.fromdecimalstr("+12345678901234567890523897987")
+        assert x.tolong() == 12345678901234567890523897987L
+        assert x.tobool() is True
+        x = rbigint.fromdecimalstr("-12345678901234567890523897987")
+        assert x.tolong() == -12345678901234567890523897987L
+        assert x.tobool() is True
+        x = rbigint.fromdecimalstr("+0")
+        assert x.tolong() == 0
+        assert x.tobool() is False
+        x = rbigint.fromdecimalstr("-0")
+        assert x.tolong() == 0
+        assert x.tobool() is False
+
     def test_add(self):
         x = 123456789123456789000000L
         y = 123858582373821923936744221L
@@ -458,6 +475,35 @@
         assert (rbigint.fromlong(-9**50).ulonglongmask() ==
                 r_ulonglong(-9**50))
 
+    def test_parse_digit_string(self):
+        from pypy.rlib.rbigint import parse_digit_string
+        class Parser:
+            def __init__(self, base, sign, digits):
+                self.base = base
+                self.sign = sign
+                self.next_digit = iter(digits + [-1]).next
+        x = parse_digit_string(Parser(10, 1, [6]))
+        assert x.eq(rbigint.fromint(6))
+        x = parse_digit_string(Parser(10, 1, [6, 2, 3]))
+        assert x.eq(rbigint.fromint(623))
+        x = parse_digit_string(Parser(10, -1, [6, 2, 3]))
+        assert x.eq(rbigint.fromint(-623))
+        x = parse_digit_string(Parser(16, 1, [0xA, 0x4, 0xF]))
+        assert x.eq(rbigint.fromint(0xA4F))
+        num = 0
+        for i in range(36):
+            x = parse_digit_string(Parser(36, 1, range(i)))
+            assert x.eq(rbigint.fromlong(num))
+            num = num * 36 + i
+        x = parse_digit_string(Parser(16, -1, range(15,-1,-1)*99))
+        assert x.eq(rbigint.fromlong(long('-0x' + 'FEDCBA9876543210'*99, 16)))
+        assert x.tobool() is True
+        x = parse_digit_string(Parser(7, 1, [0, 0, 0]))
+        assert x.tobool() is False
+        x = parse_digit_string(Parser(7, -1, [0, 0, 0]))
+        assert x.tobool() is False
+
+
 BASE = 2 ** SHIFT
 
 class TestTranslatable(object):

Modified: pypy/branch/fast-forward/pypy/rpython/lltypesystem/rdict.py
==============================================================================
--- pypy/branch/fast-forward/pypy/rpython/lltypesystem/rdict.py	(original)
+++ pypy/branch/fast-forward/pypy/rpython/lltypesystem/rdict.py	Tue Nov  9 00:03:02 2010
@@ -306,6 +306,13 @@
         hop.exception_cannot_occur()
         return hop.gendirectcall(ll_clear, v_dict)
 
+    def rtype_method_popitem(self, hop):
+        v_dict, = hop.inputargs(self)
+        r_tuple = hop.r_result
+        cTUPLE = hop.inputconst(lltype.Void, r_tuple.lowleveltype)
+        hop.exception_is_here()
+        return hop.gendirectcall(ll_popitem, cTUPLE, v_dict)
+
 class __extend__(pairtype(DictRepr, rmodel.Repr)): 
 
     def rtype_getitem((r_dict, r_key), hop):
@@ -465,6 +472,10 @@
     i = ll_dict_lookup(d, key, d.keyhash(key))
     if not d.entries.valid(i):
         raise KeyError
+    _ll_dict_del(d, i)
+ll_dict_delitem.oopspec = 'dict.delitem(d, key)'
+
+def _ll_dict_del(d, i):
     d.entries.mark_deleted(i)
     d.num_items -= 1
     # clear the key and the value if they are GC pointers
@@ -481,7 +492,6 @@
     num_entries = len(d.entries)
     if num_entries > DICT_INITSIZE and d.num_items < num_entries / 4:
         ll_dict_resize(d)
-ll_dict_delitem.oopspec = 'dict.delitem(d, key)'
 
 def ll_dict_resize(d):
     old_entries = d.entries
@@ -810,3 +820,26 @@
     i = ll_dict_lookup(d, key, d.keyhash(key))
     return d.entries.valid(i)
 ll_contains.oopspec = 'dict.contains(d, key)'
+
+POPITEMINDEX = lltype.Struct('PopItemIndex', ('nextindex', lltype.Signed))
+global_popitem_index = lltype.malloc(POPITEMINDEX, zero=True, immortal=True)
+
+def ll_popitem(ELEM, dic):
+    entries = dic.entries
+    dmask = len(entries) - 1
+    base = global_popitem_index.nextindex
+    counter = 0
+    while counter <= dmask:
+        i = (base + counter) & dmask
+        counter += 1
+        if entries.valid(i):
+            break
+    else:
+        raise KeyError
+    global_popitem_index.nextindex += counter
+    entry = entries[i]
+    r = lltype.malloc(ELEM.TO)
+    r.item0 = recast(ELEM.TO.item0, entry.key)
+    r.item1 = recast(ELEM.TO.item1, entry.value)
+    _ll_dict_del(dic, i)
+    return r

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	Tue Nov  9 00:03:02 2010
@@ -178,6 +178,7 @@
         self.nursery      = NULL
         self.nursery_free = NULL
         self.nursery_top  = NULL
+        self.debug_always_do_minor_collect = False
         #
         # The ArenaCollection() handles the nonmovable objects allocation.
         if ArenaCollectionClass is None:
@@ -245,6 +246,10 @@
             # From there on, the GC is fully initialized and the code
             # below can use it
             newsize = base.read_from_env('PYPY_GC_NURSERY')
+            # PYPY_GC_NURSERY=1 forces a minor collect for every malloc.
+            # Useful to debug external factors, like trackgcroot or the
+            # handling of the write barrier.
+            self.debug_always_do_minor_collect = newsize == 1
             if newsize <= 0:
                 newsize = generation.estimate_best_nursery_size()
                 if newsize <= 0:
@@ -444,6 +449,10 @@
         result = self.nursery_free
         self.nursery_free = result + totalsize
         ll_assert(self.nursery_free <= self.nursery_top, "nursery overflow")
+        #
+        if self.debug_always_do_minor_collect:
+            self.nursery_free = self.nursery_top
+        #
         return result
     collect_and_reserve._dont_inline_ = True
 

Modified: pypy/branch/fast-forward/pypy/rpython/test/test_rdict.py
==============================================================================
--- pypy/branch/fast-forward/pypy/rpython/test/test_rdict.py	(original)
+++ pypy/branch/fast-forward/pypy/rpython/test/test_rdict.py	Tue Nov  9 00:03:02 2010
@@ -682,6 +682,26 @@
         # if it does not crash, we are fine. It crashes if you forget the hash field.
         self.interpret(func, [])
 
+    def test_dict_popitem(self):
+        def func():
+            d = {}
+            d[5] = 2
+            d[6] = 3
+            k1, v1 = d.popitem()
+            assert len(d) == 1
+            k2, v2 = d.popitem()
+            try:
+                d.popitem()
+            except KeyError:
+                pass
+            else:
+                assert 0, "should have raised KeyError"
+            assert len(d) == 0
+            return k1*1000 + v1*100 + k2*10 + v2
+
+        res = self.interpret(func, [])
+        assert res in [5263, 6352]
+
     # ____________________________________________________________
 
     def test_opt_nullkeymarker(self):

Modified: pypy/branch/fast-forward/pypy/tool/alarm.py
==============================================================================
--- pypy/branch/fast-forward/pypy/tool/alarm.py	(original)
+++ pypy/branch/fast-forward/pypy/tool/alarm.py	Tue Nov  9 00:03:02 2010
@@ -38,8 +38,9 @@
     sys.path.insert(0, os.path.dirname(sys.argv[0]))
     return sys.argv[0]
 
-finished = []
-try:
-    execfile(_main_with_alarm(finished))
-finally:
-    finished.append(True)
+if __name__ == '__main__':
+    finished = []
+    try:
+        execfile(_main_with_alarm(finished))
+    finally:
+        finished.append(True)

Modified: pypy/branch/fast-forward/pypy/tool/readdictinfo.py
==============================================================================
--- pypy/branch/fast-forward/pypy/tool/readdictinfo.py	(original)
+++ pypy/branch/fast-forward/pypy/tool/readdictinfo.py	Tue Nov  9 00:03:02 2010
@@ -7,37 +7,38 @@
 
 import sys
 
-infile = open(sys.argv[1])
+if __name__ == '__main__':
+    infile = open(sys.argv[1])
 
-curr = None
-slots = []
-for line in infile:
-    if line == '------------------\n':
-        if curr:
-            break
-        curr = 1
-    else:
-        attr, val = [s.strip() for s in line.split(':')]
-        slots.append(attr)
+    curr = None
+    slots = []
+    for line in infile:
+        if line == '------------------\n':
+            if curr:
+                break
+            curr = 1
+        else:
+            attr, val = [s.strip() for s in line.split(':')]
+            slots.append(attr)
 
-class DictInfo(object):
-    __slots__ = slots
+    class DictInfo(object):
+        __slots__ = slots
 
-infile = open(sys.argv[1])
+    infile = open(sys.argv[1])
 
-infos = []
+    infos = []
 
-for line in infile:
-    if line == '------------------\n':
-        curr = object.__new__(DictInfo)
-        infos.append(curr)
-    else:
-        attr, val = [s.strip() for s in line.split(':')]
-        if '.' in val:
-            val = float(val)
+    for line in infile:
+        if line == '------------------\n':
+            curr = object.__new__(DictInfo)
+            infos.append(curr)
         else:
-            val = int(val)
-        setattr(curr, attr, val)
+            attr, val = [s.strip() for s in line.split(':')]
+            if '.' in val:
+                val = float(val)
+            else:
+                val = int(val)
+            setattr(curr, attr, val)
 
 def histogram(infos, keyattr, *attrs):
     r = {}

Modified: pypy/branch/fast-forward/pypy/tool/rundictbenchmarks.py
==============================================================================
--- pypy/branch/fast-forward/pypy/tool/rundictbenchmarks.py	(original)
+++ pypy/branch/fast-forward/pypy/tool/rundictbenchmarks.py	Tue Nov  9 00:03:02 2010
@@ -7,20 +7,21 @@
 # need to hack a copy of rst2html for yourself (svn docutils
 # required).
 
-try:
-    os.unlink("dictinfo.txt")
-except os.error:
-    pass
+if __name__ == '__main__':
+    try:
+        os.unlink("dictinfo.txt")
+    except os.error:
+        pass
 
-progs = [('pystone', ['-c', 'from test import pystone; pystone.main()']),
-         ('richards', ['richards.py']),
-         ('docutils', ['rst2html.py', '../../doc/coding-guide.txt', 'foo.html']),
-         ('translate', ['translate.py', '--backendopt', '--no-compile', '--batch',
-                        'targetrpystonedalone.py'])
-         ]
+    progs = [('pystone', ['-c', 'from test import pystone; pystone.main()']),
+             ('richards', ['richards.py']),
+             ('docutils', ['rst2html.py', '../../doc/coding-guide.txt', 'foo.html']),
+             ('translate', ['translate.py', '--backendopt', '--no-compile', '--batch',
+                            'targetrpystonedalone.py'])
+             ]
 
-EXE = sys.argv[1]
+    EXE = sys.argv[1]
 
-for suffix, args in progs:
-    os.spawnv(os.P_WAIT, EXE, [EXE] + args)
-    os.rename('dictinfo.txt', 'dictinfo-%s.txt'%suffix)
+    for suffix, args in progs:
+        os.spawnv(os.P_WAIT, EXE, [EXE] + args)
+        os.rename('dictinfo.txt', 'dictinfo-%s.txt'%suffix)

Modified: pypy/branch/fast-forward/pypy/tool/statistic_irc_log.py
==============================================================================
--- pypy/branch/fast-forward/pypy/tool/statistic_irc_log.py	(original)
+++ pypy/branch/fast-forward/pypy/tool/statistic_irc_log.py	Tue Nov  9 00:03:02 2010
@@ -2,53 +2,54 @@
 from os import system, chdir
 from urllib import urlopen
 
-log_URL = 'http://tismerysoft.de/pypy/irc-logs/'
-archive_FILENAME = 'pypy.tar.gz'
-
-tempdir = py.test.ensuretemp("irc-log")
-
-# get compressed archive
-chdir( str(tempdir))
-system('wget -q %s%s' % (log_URL, archive_FILENAME))
-system('tar xzf %s'   % archive_FILENAME)
-chdir('pypy')
-
-# get more recent daily logs
-pypydir = tempdir.join('pypy')
-for line in urlopen(log_URL + 'pypy/').readlines():
-    i = line.find('%23pypy.log.')
-    if i == -1:
-        continue
-    filename = line[i:].split('"')[0]
-    system('wget -q %spypy/%s' % (log_URL, filename))
-
-# rename to YYYYMMDD
-for log_filename in pypydir.listdir('#pypy.log.*'):
-    rename_to = None
-    b = log_filename.basename
-    if '-' in b:
-        rename_to = log_filename.basename.replace('-', '')
-    elif len(b) == 19:
-        months= 'Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec'.split()
-        day   = b[10:12]
-        month = months.index(b[12:15]) + 1
-        year  = b[15:20]
-        rename_to = '#pypy.log.%04s%02d%02s' % (year, month, day)
-
-    if rename_to:
-        log_filename.rename(rename_to)
-        #print 'RENAMED', log_filename, 'TO', rename_to
-
-# print sorted list of filenames of daily logs
-print 'irc://irc.freenode.org/pypy'
-print 'date, messages, visitors'
-for log_filename in pypydir.listdir('#pypy.log.*'):
-    n_messages, visitors = 0, {}
-    f = str(log_filename)
-    for s in file(f):
-        if '<' in s and '>' in s:
-            n_messages += 1
-        elif ' joined #pypy' in s:
-            v = s.split()[1]
-            visitors[v] = True
-    print '%04s-%02s-%02s, %d, %d' % (f[-8:-4], f[-4:-2], f[-2:], n_messages, len(visitors.keys()))
+if __name__ == '__main__':
+    log_URL = 'http://tismerysoft.de/pypy/irc-logs/'
+    archive_FILENAME = 'pypy.tar.gz'
+
+    tempdir = py.test.ensuretemp("irc-log")
+
+    # get compressed archive
+    chdir( str(tempdir))
+    system('wget -q %s%s' % (log_URL, archive_FILENAME))
+    system('tar xzf %s'   % archive_FILENAME)
+    chdir('pypy')
+
+    # get more recent daily logs
+    pypydir = tempdir.join('pypy')
+    for line in urlopen(log_URL + 'pypy/').readlines():
+        i = line.find('%23pypy.log.')
+        if i == -1:
+            continue
+        filename = line[i:].split('"')[0]
+        system('wget -q %spypy/%s' % (log_URL, filename))
+
+    # rename to YYYYMMDD
+    for log_filename in pypydir.listdir('#pypy.log.*'):
+        rename_to = None
+        b = log_filename.basename
+        if '-' in b:
+            rename_to = log_filename.basename.replace('-', '')
+        elif len(b) == 19:
+            months= 'Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec'.split()
+            day   = b[10:12]
+            month = months.index(b[12:15]) + 1
+            year  = b[15:20]
+            rename_to = '#pypy.log.%04s%02d%02s' % (year, month, day)
+
+        if rename_to:
+            log_filename.rename(rename_to)
+            #print 'RENAMED', log_filename, 'TO', rename_to
+
+    # print sorted list of filenames of daily logs
+    print 'irc://irc.freenode.org/pypy'
+    print 'date, messages, visitors'
+    for log_filename in pypydir.listdir('#pypy.log.*'):
+        n_messages, visitors = 0, {}
+        f = str(log_filename)
+        for s in file(f):
+            if '<' in s and '>' in s:
+                n_messages += 1
+            elif ' joined #pypy' in s:
+                v = s.split()[1]
+                visitors[v] = True
+        print '%04s-%02s-%02s, %d, %d' % (f[-8:-4], f[-4:-2], f[-2:], n_messages, len(visitors.keys()))

Modified: pypy/branch/fast-forward/pypy/tool/watchdog.py
==============================================================================
--- pypy/branch/fast-forward/pypy/tool/watchdog.py	(original)
+++ pypy/branch/fast-forward/pypy/tool/watchdog.py	Tue Nov  9 00:03:02 2010
@@ -7,9 +7,6 @@
             return name
     return 'signal %d' % (n,)
 
-timeout = float(sys.argv[1])
-timedout = False
-
 def childkill():
     global timedout
     timedout = True
@@ -20,31 +17,35 @@
     except OSError:
         pass
 
-pid = os.fork()
-if pid == 0:
-    os.execvp(sys.argv[2], sys.argv[2:])
-else: # parent
-    t = threading.Timer(timeout, childkill)
-    t.start()
-    while True:
-        try:
-            pid, status = os.waitpid(pid, 0)
-        except KeyboardInterrupt:
-            continue
+if __name__ == '__main__':
+    timeout = float(sys.argv[1])
+    timedout = False
+
+    pid = os.fork()
+    if pid == 0:
+        os.execvp(sys.argv[2], sys.argv[2:])
+    else: # parent
+        t = threading.Timer(timeout, childkill)
+        t.start()
+        while True:
+            try:
+                pid, status = os.waitpid(pid, 0)
+            except KeyboardInterrupt:
+                continue
+            else:
+                t.cancel()
+                break
+        if os.WIFEXITED(status):
+            sys.exit(os.WEXITSTATUS(status))
         else:
-            t.cancel()
-            break
-    if os.WIFEXITED(status):
-        sys.exit(os.WEXITSTATUS(status))
-    else:
-        assert os.WIFSIGNALED(status)
-        sign = os.WTERMSIG(status)
-        if timedout and sign == signal.SIGTERM:
+            assert os.WIFSIGNALED(status)
+            sign = os.WTERMSIG(status)
+            if timedout and sign == signal.SIGTERM:
+                sys.exit(1)
+            signame = getsignalname(sign)
+            sys.stderr.write("="*26 + "timedout" + "="*26 + "\n")        
+            sys.stderr.write("="*25 + " %-08s " %  signame + "="*25 + "\n")
             sys.exit(1)
-        signame = getsignalname(sign)
-        sys.stderr.write("="*26 + "timedout" + "="*26 + "\n")        
-        sys.stderr.write("="*25 + " %-08s " %  signame + "="*25 + "\n")
-        sys.exit(1)
 
-    
-    
+
+

Modified: pypy/branch/fast-forward/pypy/tool/watchdog_nt.py
==============================================================================
--- pypy/branch/fast-forward/pypy/tool/watchdog_nt.py	(original)
+++ pypy/branch/fast-forward/pypy/tool/watchdog_nt.py	Tue Nov  9 00:03:02 2010
@@ -2,11 +2,6 @@
 import threading
 import ctypes
 
-PROCESS_TERMINATE = 0x1
-
-timeout = float(sys.argv[1])
-timedout = False
-
 def childkill(pid):
     global timedout
     timedout = True
@@ -14,19 +9,25 @@
     sys.stderr.write("="*26 + "timedout" + "="*26 + "\n")
     ctypes.windll.kernel32.TerminateProcess(pid, 1)
 
-pid = os.spawnv(os.P_NOWAIT, sys.argv[2], sys.argv[2:])
+if __name__ == '__main__':
+    PROCESS_TERMINATE = 0x1
+
+    timeout = float(sys.argv[1])
+    timedout = False
+
+    pid = os.spawnv(os.P_NOWAIT, sys.argv[2], sys.argv[2:])
+
+    t = threading.Timer(timeout, childkill, (pid,))
+    t.start()
+    while True:
+        try:
+            pid, status = os.waitpid(pid, 0)
+        except KeyboardInterrupt:
+            continue
+        else:
+            t.cancel()
+            break
+
+    #print 'status ', status >> 8
+    sys.exit(status >> 8)
 
-t = threading.Timer(timeout, childkill, (pid,))
-t.start()
-while True:
-    try:
-        pid, status = os.waitpid(pid, 0)
-    except KeyboardInterrupt:
-        continue
-    else:
-        t.cancel()
-        break
-
-#print 'status ', status >> 8
-sys.exit(status >> 8)
-    

Modified: pypy/branch/fast-forward/pypy/translator/c/gcc/test/test_trackgcroot.py
==============================================================================
--- pypy/branch/fast-forward/pypy/translator/c/gcc/test/test_trackgcroot.py	(original)
+++ pypy/branch/fast-forward/pypy/translator/c/gcc/test/test_trackgcroot.py	Tue Nov  9 00:03:02 2010
@@ -109,7 +109,7 @@
  
 def test_computegcmaptable():
     tests = []
-    for format in ('elf', 'darwin', 'msvc', 'elf64'):
+    for format in ('elf', 'elf64', 'darwin', 'darwin64', 'msvc'):
         for path in this_dir.join(format).listdir("track*.s"):
             n = path.purebasename[5:]
             try:

Modified: pypy/branch/fast-forward/pypy/translator/c/gcc/trackgcroot.py
==============================================================================
--- pypy/branch/fast-forward/pypy/translator/c/gcc/trackgcroot.py	(original)
+++ pypy/branch/fast-forward/pypy/translator/c/gcc/trackgcroot.py	Tue Nov  9 00:03:02 2010
@@ -455,7 +455,7 @@
         'inc', 'dec', 'not', 'neg', 'or', 'and', 'sbb', 'adc',
         'shl', 'shr', 'sal', 'sar', 'rol', 'ror', 'mul', 'imul', 'div', 'idiv',
         'bswap', 'bt', 'rdtsc',
-        'punpck', 'pshufd', 
+        'punpck', 'pshufd', 'psll',
         # zero-extending moves should not produce GC pointers
         'movz',
         ])
@@ -1090,7 +1090,7 @@
 
 ElfFunctionGcRootTracker64.init_regexp()
 
-class DarwinFunctionGcRootTracker(ElfFunctionGcRootTracker32):
+class DarwinFunctionGcRootTracker32(ElfFunctionGcRootTracker32):
     format = 'darwin'
     function_names_prefix = '_'
 
@@ -1102,7 +1102,22 @@
         funcname = '_' + match.group(1)
         FunctionGcRootTracker32.__init__(self, funcname, lines, filetag)
 
-class Mingw32FunctionGcRootTracker(DarwinFunctionGcRootTracker):
+class DarwinFunctionGcRootTracker64(ElfFunctionGcRootTracker64):
+    format = 'darwin64'
+    function_names_prefix = '_'
+
+    LABEL = ElfFunctionGcRootTracker32.LABEL
+    r_jmptable_item = re.compile(r"\t.(?:long|quad)\t"+LABEL+"(-\"?[A-Za-z0-9$]+\"?)?\s*$")
+
+    r_functionstart = re.compile(r"_(\w+):\s*$")
+    OFFSET_LABELS   = 0
+
+    def __init__(self, lines, filetag=0):
+        match = self.r_functionstart.match(lines[0])
+        funcname = '_' + match.group(1)
+        FunctionGcRootTracker64.__init__(self, funcname, lines, filetag)
+
+class Mingw32FunctionGcRootTracker(DarwinFunctionGcRootTracker32):
     format = 'mingw32'
     function_names_prefix = '_'
 
@@ -1373,7 +1388,7 @@
 
 class DarwinAssemblerParser(AssemblerParser):
     format = "darwin"
-    FunctionGcRootTracker = DarwinFunctionGcRootTracker
+    FunctionGcRootTracker = DarwinFunctionGcRootTracker32
 
     r_textstart = re.compile(r"\t.text\s*$")
 
@@ -1419,6 +1434,10 @@
         return super(DarwinAssemblerParser, self).process_function(
             lines, entrypoint, filename)
 
+class DarwinAssemblerParser64(DarwinAssemblerParser):
+    format = "darwin64"
+    FunctionGcRootTracker = DarwinFunctionGcRootTracker64
+
 class Mingw32AssemblerParser(DarwinAssemblerParser):
     format = "mingw32"
     FunctionGcRootTracker = Mingw32FunctionGcRootTracker
@@ -1542,6 +1561,7 @@
     'elf': ElfAssemblerParser,
     'elf64': ElfAssemblerParser64,
     'darwin': DarwinAssemblerParser,
+    'darwin64': DarwinAssemblerParser64,
     'mingw32': Mingw32AssemblerParser,
     'msvc': MsvcAssemblerParser,
     }
@@ -1579,7 +1599,7 @@
             txt = kwargs[self.format]
             print >> output, "\t%s" % txt
 
-        if self.format == 'elf64':
+        if self.format in ('elf64', 'darwin64'):
             word_decl = '.quad'
         else:
             word_decl = '.long'
@@ -1632,10 +1652,11 @@
                }
             }
             """
-        elif self.format == 'elf64':
+        elif self.format in ('elf64', 'darwin64'):
             print >> output, "\t.text"
             print >> output, "\t.globl %s" % _globalname('pypy_asm_stackwalk')
-            print >> output, "\t.type pypy_asm_stackwalk, @function"
+            _variant(elf64='.type pypy_asm_stackwalk, @function',
+                     darwin64='')
             print >> output, "%s:" % _globalname('pypy_asm_stackwalk')
 
             print >> output, """\
@@ -1680,8 +1701,9 @@
             /* the return value is the one of the 'call' above, */
             /* because %rax (and possibly %rdx) are unmodified  */
             ret
-            .size pypy_asm_stackwalk, .-pypy_asm_stackwalk
             """
+            _variant(elf64='.size pypy_asm_stackwalk, .-pypy_asm_stackwalk',
+                     darwin64='')
         else:
             print >> output, "\t.text"
             print >> output, "\t.globl %s" % _globalname('pypy_asm_stackwalk')
@@ -1808,6 +1830,7 @@
             _variant(elf='.section\t.rodata',
                      elf64='.section\t.rodata',
                      darwin='.const',
+                     darwin64='.const',
                      mingw32='')
 
             print >> output, """\
@@ -1881,11 +1904,14 @@
 
 
 if __name__ == '__main__':
-    verbose = 1
+    verbose = 0
     shuffle = False
     output_raw_table = False
     if sys.platform == 'darwin':
-        format = 'darwin'
+        if sys.maxint > 2147483647:
+            format = 'darwin64'
+        else:
+            format = 'darwin'
     elif sys.platform == 'win32':
         format = 'mingw32'
     else:

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	Tue Nov  9 00:03:02 2010
@@ -623,9 +623,16 @@
                 mk.definition('OBJECTS', '$(ASMLBLFILES) gcmaptable.s')
                 mk.rule('%.s', '%.c', '$(CC) $(CFLAGS) $(CFLAGSEXTRA) -frandom-seed=$< -o $@ -S $< $(INCLUDEDIRS)')
                 mk.rule('%.lbl.s %.gcmap', '%.s',
-                        python + '$(PYPYDIR)/translator/c/gcc/trackgcroot.py -m$(PYPY_MAIN_FUNCTION) -t $< > $*.gcmap')
+                        [python +
+                             '$(PYPYDIR)/translator/c/gcc/trackgcroot.py '
+                             '-m$(PYPY_MAIN_FUNCTION) -t $< > $*.gctmp',
+                         'mv $*.gctmp $*.gcmap'])
                 mk.rule('gcmaptable.s', '$(GCMAPFILES)',
-                        python + '$(PYPYDIR)/translator/c/gcc/trackgcroot.py $(GCMAPFILES) > $@')
+                        [python +
+                             '$(PYPYDIR)/translator/c/gcc/trackgcroot.py '
+                             '$(GCMAPFILES) > $@.tmp',
+                         'mv $@.tmp $@'])
+                mk.rule('.PRECIOUS', '%.s', "# don't remove .s files if Ctrl-C'ed")
 
         else:
             mk.definition('DEBUGFLAGS', '-O1 -g')

Modified: pypy/branch/fast-forward/pypy/translator/c/src/g_include.h
==============================================================================
--- pypy/branch/fast-forward/pypy/translator/c/src/g_include.h	(original)
+++ pypy/branch/fast-forward/pypy/translator/c/src/g_include.h	Tue Nov  9 00:03:02 2010
@@ -39,9 +39,10 @@
 #include "src/instrument.h"
 
 /* optional assembler bits */
-#if defined(__GNUC__) && defined(__i386__)
-#  include "src/asm_gcc_x86.h"
-#endif
+// disabled: does not give any speed-up
+//#if defined(__GNUC__) && defined(__i386__)
+//#  include "src/asm_gcc_x86.h"
+//#endif
 
 #if defined(__GNUC__) && defined(__ppc__)
 #  include "src/asm_ppc.h"

Modified: pypy/branch/fast-forward/pypy/translator/c/src/int.h
==============================================================================
--- pypy/branch/fast-forward/pypy/translator/c/src/int.h	(original)
+++ pypy/branch/fast-forward/pypy/translator/c/src/int.h	Tue Nov  9 00:03:02 2010
@@ -2,40 +2,27 @@
 /************************************************************/
  /***  C header subsection: operations between ints        ***/
 
-#ifndef LLONG_MAX
-# if SIZEOF_LONG_LONG == 8
-#  define LLONG_MAX 0X7FFFFFFFFFFFFFFFLL
-# else
-#  error "fix LLONG_MAX"
-# endif
-#endif
-
-#ifndef LLONG_MIN
-# define LLONG_MIN (-LLONG_MAX-1)
-#endif
 
 /*** unary operations ***/
 
-#define OP_INT_IS_TRUE(x,r)   OP_INT_NE(x,0,r)
-
-#define OP_INT_INVERT(x,r)    r = ~((x))
-
-#define OP_INT_NEG(x,r)    r = -(x)
+#define OP_INT_IS_TRUE(x,r)   r = ((x) != 0)
+#define OP_INT_INVERT(x,r)    r = ~(x)
+#define OP_INT_NEG(x,r)       r = -(x)
 
 #define OP_INT_NEG_OVF(x,r) \
-    if ((x) == LONG_MIN) FAIL_OVF("integer negate"); \
+	if ((x) == LONG_MIN) FAIL_OVF("integer negate"); \
 	OP_INT_NEG(x,r)
 #define OP_LLONG_NEG_OVF(x,r) \
-    if ((x) == LLONG_MIN) FAIL_OVF("integer negate"); \
+	if ((x) == LLONG_MIN) FAIL_OVF("integer negate"); \
 	OP_LLONG_NEG(x,r)
 
 #define OP_INT_ABS(x,r)    r = (x) >= 0 ? x : -(x)
 
 #define OP_INT_ABS_OVF(x,r) \
-    if ((x) == LONG_MIN) FAIL_OVF("integer absolute"); \
+	if ((x) == LONG_MIN) FAIL_OVF("integer absolute"); \
 	OP_INT_ABS(x,r)
 #define OP_LLONG_ABS_OVF(x,r) \
-    if ((x) == LLONG_MIN) FAIL_OVF("integer absolute"); \
+	if ((x) == LLONG_MIN) FAIL_OVF("integer absolute"); \
 	OP_LLONG_ABS(x,r)
 
 /***  binary operations ***/
@@ -59,50 +46,46 @@
 
 #define OP_INT_ADD(x,y,r)     r = (x) + (y)
 
+/* cast to avoid undefined behaviour on overflow */
 #define OP_INT_ADD_OVF(x,y,r) \
-	OP_INT_ADD(x,y,r); \
-	if ((r^(x)) >= 0 || (r^(y)) >= 0); \
-	else FAIL_OVF("integer addition")
+        r = (long)((unsigned long)x + y); \
+        if ((r^x) < 0 && (r^y) < 0) FAIL_OVF("integer addition")
+
+#define OP_LLONG_ADD_OVF(x,y,r) \
+        r = (long long)((unsigned long long)x + y); \
+        if ((r^x) < 0 && (r^y) < 0) FAIL_OVF("integer addition")
 
 #define OP_INT_ADD_NONNEG_OVF(x,y,r)  /* y can be assumed >= 0 */ \
-    r = (long)((unsigned long)x + (unsigned long)y); \
-    if (r >= (x)); \
-    else FAIL_OVF("integer addition")
-/* Can a C compiler be too clever and think it can "prove" that
- * r >= x always holds above?  Yes.  Hence the casting. */
+        r = (long)((unsigned long)x + y); \
+        if ((r&~x) < 0) FAIL_OVF("integer addition")
 
 #define OP_INT_SUB(x,y,r)     r = (x) - (y)
 
 #define OP_INT_SUB_OVF(x,y,r) \
-	OP_INT_SUB(x,y,r); \
-	if ((r^(x)) >= 0 || (r^~(y)) >= 0); \
-	else FAIL_OVF("integer subtraction")
-
-#define OP_INT_MUL(x,y,r)     r = (x) * (y)
-
-#if defined(HAVE_LONG_LONG) && SIZE_OF_LONG_LONG < SIZE_OF_LONG
-#  define OP_INT_MUL_OVF_LL      1
-#lse
-#  define OP_INT_MUL_OVF_LL      0
-#endif
+        r = (long)((unsigned long)x - y); \
+        if ((r^x) < 0 && (r^~y) < 0) FAIL_OVF("integer subtraction")
 
-#if !OP_INT_MUL_OVF_LL
+#define OP_LLONG_SUB_OVF(x,y,r) \
+        r = (long long)((unsigned long long)x - y); \
+        if ((r^x) < 0 && (r^~y) < 0) FAIL_OVF("integer subtraction")
 
-#define OP_INT_MUL_OVF(x,y,r) \
-	if (op_int_mul_ovf(x,y,&r)); \
-	else FAIL_OVF("integer multiplication")
-
-#else
+#define OP_INT_MUL(x,y,r)     r = (x) * (y)
 
+#if SIZEOF_LONG * 2 <= SIZEOF_LONG_LONG
 #define OP_INT_MUL_OVF(x,y,r) \
 	{ \
-		PY_LONG_LONG lr = (PY_LONG_LONG)(x) * (PY_LONG_LONG)(y); \
-		r = (long)lr; \
-		if ((PY_LONG_LONG)r == lr); \
-		else FAIL_OVF("integer multiplication"); \
+		long long _lr = (long long)x * y; \
+		r = (long)_lr; \
+		if (_lr != (long long)r) FAIL_OVF("integer multiplication"); \
 	}
+#else
+#define OP_INT_MUL_OVF(x,y,r) \
+	r = op_llong_mul_ovf(x, y)   /* long == long long */
 #endif
 
+#define OP_LLONG_MUL_OVF(x,y,r) \
+	r = op_llong_mul_ovf(x, y)
+
 /* shifting */
 
 /* NB. shifting has same limitations as C: the shift count must be
@@ -121,6 +104,10 @@
 	OP_INT_LSHIFT(x,y,r); \
 	if ((x) != Py_ARITHMETIC_RIGHT_SHIFT(long, r, (y))) \
 		FAIL_OVF("x<<y losing bits or changing sign")
+#define OP_LLONG_LSHIFT_OVF(x,y,r) \
+	OP_LLONG_LSHIFT(x,y,r); \
+	if ((x) != Py_ARITHMETIC_RIGHT_SHIFT(PY_LONG_LONG, r, (y))) \
+		FAIL_OVF("x<<y losing bits or changing sign")
 
 /* floor division */
 
@@ -129,27 +116,48 @@
 #define OP_LLONG_FLOORDIV(x,y,r)  r = (x) / (y)
 #define OP_ULLONG_FLOORDIV(x,y,r) r = (x) / (y)
 
-#define OP_INT_FLOORDIV_OVF(x,y,r) \
-	if ((y) == -1 && (x) == LONG_MIN) \
-            { FAIL_OVF("integer division"); } \
-        else OP_INT_FLOORDIV(x,y,r)
-
-#define OP_INT_FLOORDIV_ZER(x,y,r) \
-	if ((y)) { OP_INT_FLOORDIV(x,y,r); } \
-	else FAIL_ZER("integer division")
-#define OP_UINT_FLOORDIV_ZER(x,y,r) \
-	if ((y)) { OP_UINT_FLOORDIV(x,y,r); } \
-	else FAIL_ZER("unsigned integer division")
-#define OP_LLONG_FLOORDIV_ZER(x,y,r) \
-	if ((y)) { OP_LLONG_FLOORDIV(x,y,r); } \
-	else FAIL_ZER("integer division")
-#define OP_ULLONG_FLOORDIV_ZER(x,y,r) \
-	if ((y)) { OP_ULLONG_FLOORDIV(x,y,r); } \
-	else FAIL_ZER("unsigned integer division")
-
-#define OP_INT_FLOORDIV_OVF_ZER(x,y,r) \
-	if ((y)) { OP_INT_FLOORDIV_OVF(x,y,r); } \
-	else FAIL_ZER("integer division")
+#define OP_INT_FLOORDIV_OVF(x,y,r)                      \
+	if ((y) == -1 && (x) == LONG_MIN)               \
+	    { FAIL_OVF("integer division"); r=0; }      \
+	else                                            \
+	    r = (x) / (y)
+#define OP_LLONG_FLOORDIV_OVF(x,y,r)                    \
+	if ((y) == -1 && (x) == LLONG_MIN)              \
+	    { FAIL_OVF("integer division"); r=0; }      \
+	else                                            \
+	    r = (x) / (y)
+
+#define OP_INT_FLOORDIV_ZER(x,y,r)                      \
+	if ((y) == 0)                                   \
+	    { FAIL_ZER("integer division"); r=0; }      \
+	else                                            \
+	    r = (x) / (y)
+#define OP_UINT_FLOORDIV_ZER(x,y,r)                             \
+	if ((y) == 0)                                           \
+	    { FAIL_ZER("unsigned integer division"); r=0; }     \
+	else                                                    \
+	    r = (x) / (y)
+#define OP_LLONG_FLOORDIV_ZER(x,y,r)                    \
+	if ((y) == 0)                                   \
+	    { FAIL_ZER("integer division"); r=0; }      \
+	else                                            \
+	    r = (x) / (y)
+#define OP_ULLONG_FLOORDIV_ZER(x,y,r)                           \
+	if ((y) == 0)                                           \
+	    { FAIL_ZER("unsigned integer division"); r=0; }     \
+	else                                                    \
+	    r = (x) / (y)
+
+#define OP_INT_FLOORDIV_OVF_ZER(x,y,r)                  \
+	if ((y) == 0)                                   \
+	    { FAIL_ZER("integer division"); r=0; }      \
+	else                                            \
+	    { OP_INT_FLOORDIV_OVF(x,y,r); }
+#define OP_LLONG_FLOORDIV_OVF_ZER(x,y,r)                \
+	if ((y) == 0)                                   \
+	    { FAIL_ZER("integer division"); r=0; }      \
+	else                                            \
+	    { OP_LLONG_FLOORDIV_OVF(x,y,r); }
 
 /* modulus */
 
@@ -158,27 +166,47 @@
 #define OP_LLONG_MOD(x,y,r)   r = (x) % (y)
 #define OP_ULLONG_MOD(x,y,r)  r = (x) % (y)
 
-#define OP_INT_MOD_OVF(x,y,r) \
-	if ((y) == -1 && (x) == LONG_MIN) \
-            { FAIL_OVF("integer modulo"); }\
-        else OP_INT_MOD(x,y,r)
-
-#define OP_INT_MOD_ZER(x,y,r) \
-	if ((y)) { OP_INT_MOD(x,y,r); } \
-	else FAIL_ZER("integer modulo")
-#define OP_UINT_MOD_ZER(x,y,r) \
-	if ((y)) { OP_UINT_MOD(x,y,r); } \
-	else FAIL_ZER("unsigned integer modulo")
-#define OP_LLONG_MOD_ZER(x,y,r) \
-	if ((y)) { OP_LLONG_MOD(x,y,r); } \
-	else FAIL_ZER("integer modulo")
-#define OP_ULLONG_MOD_ZER(x,y,r) \
-	if ((y)) { OP_ULLONG_MOD(x,y,r); } \
-	else FAIL_ZER("integer modulo")
-
-#define OP_INT_MOD_OVF_ZER(x,y,r) \
-	if ((y)) { OP_INT_MOD_OVF(x,y,r); } \
-	else FAIL_ZER("integer modulo")
+#define OP_INT_MOD_OVF(x,y,r)                           \
+	if ((y) == -1 && (x) == LONG_MIN)               \
+	    { FAIL_OVF("integer modulo"); r=0; }        \
+	else                                            \
+	    r = (x) % (y)
+#define OP_LLONG_MOD_OVF(x,y,r)                         \
+	if ((y) == -1 && (x) == LLONG_MIN)              \
+	    { FAIL_OVF("integer modulo"); r=0; }        \
+	else                                            \
+	    r = (x) % (y)
+#define OP_INT_MOD_ZER(x,y,r)                           \
+	if ((y) == 0)                                   \
+	    { FAIL_ZER("integer modulo"); r=0; }        \
+	else                                            \
+	    r = (x) % (y)
+#define OP_UINT_MOD_ZER(x,y,r)                                  \
+	if ((y) == 0)                                           \
+	    { FAIL_ZER("unsigned integer modulo"); r=0; }       \
+	else                                                    \
+	    r = (x) % (y)
+#define OP_LLONG_MOD_ZER(x,y,r)                         \
+	if ((y) == 0)                                   \
+	    { FAIL_ZER("integer modulo"); r=0; }        \
+	else                                            \
+	    r = (x) % (y)
+#define OP_ULLONG_MOD_ZER(x,y,r)                                \
+	if ((y) == 0)                                           \
+	    { FAIL_ZER("unsigned integer modulo"); r=0; }       \
+	else                                                    \
+	    r = (x) % (y)
+
+#define OP_INT_MOD_OVF_ZER(x,y,r)                       \
+	if ((y) == 0)                                   \
+	    { FAIL_ZER("integer modulo"); r=0; }        \
+	else                                            \
+	    { OP_INT_MOD_OVF(x,y,r); }
+#define OP_LLONG_MOD_OVF_ZER(x,y,r)                     \
+	if ((y) == 0)                                   \
+	    { FAIL_ZER("integer modulo"); r=0; }        \
+	else                                            \
+	    { OP_LLONG_MOD_OVF(x,y,r); }
 
 /* bit operations */
 
@@ -208,31 +236,30 @@
 
 /* _________________ certain implementations __________________ */
 
-#if !OP_INT_MUL_OVF_LL
 /* adjusted from intobject.c, Python 2.3.3 */
 
 /* prototypes */
 
-int op_int_mul_ovf(long a, long b, long *longprod);
+long long op_llong_mul_ovf(long long a, long long b);
 
 /* implementations */
 
 #ifndef PYPY_NOT_MAIN_FILE
 
-int
-op_int_mul_ovf(long a, long b, long *longprod)
+long long op_llong_mul_ovf(long long a, long long b)
 {
 	double doubled_longprod;	/* (double)longprod */
 	double doubleprod;		/* (double)a * (double)b */
+	long long longprod;
 
-	*longprod = a * b;
+	longprod = a * b;
 	doubleprod = (double)a * (double)b;
-	doubled_longprod = (double)*longprod;
+	doubled_longprod = (double)longprod;
 
 	/* Fast path for normal case:  small multiplicands, and no info
 	   is lost in either method. */
 	if (doubled_longprod == doubleprod)
-		return 1;
+		return longprod;
 
 	/* Somebody somewhere lost info.  Close enough, or way off?  Note
 	   that a != 0 and b != 0 (else doubled_longprod == doubleprod == 0).
@@ -247,15 +274,15 @@
 		/* absdiff/absprod <= 1/32 iff
 		   32 * absdiff <= absprod -- 5 good bits is "close enough" */
 		if (32.0 * absdiff <= absprod)
-			return 1;
-		return 0;
+			return longprod;
+
+		FAIL_OVF("integer multiplication");
+		return -1;
 	}
 }
 
 #endif /* PYPY_NOT_MAIN_FILE */
 
-#endif /* !OP_INT_MUL_OVF_LL */
-
 /* implementations */
 
 #define OP_UINT_IS_TRUE OP_INT_IS_TRUE

Modified: pypy/branch/fast-forward/pypy/translator/c/src/signals.h
==============================================================================
--- pypy/branch/fast-forward/pypy/translator/c/src/signals.h	(original)
+++ pypy/branch/fast-forward/pypy/translator/c/src/signals.h	Tue Nov  9 00:03:02 2010
@@ -48,16 +48,12 @@
 /* utility to poll for signals that arrived */
 int pypysig_poll(void);   /* => signum or -1 */
 
-/* When a signal is received, the bit 30 of pypysig_occurred is set.
-   After all signals are processed by pypysig_poll(), the bit 30 is
-   cleared again.  The variable is exposed and RPython code is free to
-   use the other bits in any way. */
-#define PENDING_SIGNAL_BIT   (1 << 30)
+/* When a signal is received, pypysig_counter is set to -1. */
 /* This is a struct for the JIT. See interp_signal.py. */
 struct pypysig_long_struct {
     long value;
 };
-extern struct pypysig_long_struct pypysig_occurred;
+extern struct pypysig_long_struct pypysig_counter;
 
 /* some C tricks to get/set the variable as efficiently as possible:
    use macros when compiling as a stand-alone program, but still
@@ -65,18 +61,20 @@
 #undef pypysig_getaddr_occurred
 void *pypysig_getaddr_occurred(void);
 #ifndef PYPY_NOT_MAIN_FILE
-void *pypysig_getaddr_occurred(void) { return (void *)(&pypysig_occurred); }
+void *pypysig_getaddr_occurred(void) { return (void *)(&pypysig_counter); }
 #endif
-#define pypysig_getaddr_occurred()   ((void *)(&pypysig_occurred))
+#define pypysig_getaddr_occurred()   ((void *)(&pypysig_counter))
 
 /************************************************************/
 /* Implementation                                           */
 
 #ifndef PYPY_NOT_MAIN_FILE
 
-struct pypysig_long_struct pypysig_occurred;
-static volatile long *pypysig_occurred_v = (volatile long *)&pypysig_occurred.value;
-static volatile int pypysig_flags[NSIG];
+struct pypysig_long_struct pypysig_counter = {0};
+static char volatile pypysig_flags[NSIG] = {0};
+static int volatile pypysig_occurred = 0;
+/* pypysig_occurred is only an optimization: it tells if any
+   pypysig_flags could be set. */
 static int wakeup_fd = -1;
 
 void pypysig_ignore(int signum)
@@ -110,10 +108,11 @@
 static void signal_setflag_handler(int signum)
 {
     if (0 <= signum && signum < NSIG)
+      {
         pypysig_flags[signum] = 1;
-    /* the point of "*pypysig_occurred_v" instead of just "pypysig_occurred"
-       is the volatile declaration */
-    *pypysig_occurred_v |= PENDING_SIGNAL_BIT;
+        pypysig_occurred = 1;
+        pypysig_counter.value = -1;
+      }
 
     if (wakeup_fd != -1)
       write(wakeup_fd, "\0", 1);
@@ -135,25 +134,19 @@
 
 int pypysig_poll(void)
 {
-  /* the two commented out lines below are useful for performance in
-     normal usage of pypysig_poll(); however, pypy/module/signal/ is
-     not normal usage.  It only calls pypysig_poll() if the
-     PENDING_SIGNAL_BIT is set, and it clears that bit first. */
-
-/* if (pypysig_occurred & PENDING_SIGNAL_BIT) */
+  if (pypysig_occurred)
     {
-        int i;
-/*     pypysig_occurred &= ~PENDING_SIGNAL_BIT; */
-        for (i=0; i<NSIG; i++)
-            if (pypysig_flags[i])
-            {
-                pypysig_flags[i] = 0;
-                /* maybe another signal is pending: */
-                pypysig_occurred.value |= PENDING_SIGNAL_BIT;
-                return i;
-            }
+      int i;
+      pypysig_occurred = 0;
+      for (i=0; i<NSIG; i++)
+        if (pypysig_flags[i])
+          {
+            pypysig_flags[i] = 0;
+            pypysig_occurred = 1;   /* maybe another signal is pending */
+            return i;
+          }
     }
-    return -1;  /* no pending signal */
+  return -1;  /* no pending signal */
 }
 
 int pypysig_set_wakeup_fd(int fd)
@@ -163,6 +156,6 @@
   return old_fd;
 }
 
-#endif
+#endif  /* !PYPY_NOT_MAIN_FILE */
 
 #endif



More information about the Pypy-commit mailing list