[pypy-svn] r76976 - in pypy/branch/jit-bounds: . pypy/config pypy/jit/backend/llsupport pypy/jit/backend/llsupport/test pypy/jit/backend/test pypy/jit/backend/x86 pypy/jit/backend/x86/test pypy/jit/metainterp pypy/jit/metainterp/optimizeopt pypy/module/_ssl pypy/module/_winreg pypy/module/array/benchmark pypy/module/array/test pypy/module/pypyjit/test pypy/objspace/flow pypy/rlib pypy/rpython/lltypesystem pypy/rpython/lltypesystem/test pypy/rpython/memory pypy/rpython/memory/gctransform pypy/rpython/module pypy/rpython/test pypy/rpython/tool pypy/rpython/tool/test pypy/translator/c pypy/translator/c/gcc pypy/translator/c/gcc/test pypy/translator/c/gcc/test/elf64 pypy/translator/platform

hakanardo at codespeak.net hakanardo at codespeak.net
Thu Sep 9 18:10:23 CEST 2010


Author: hakanardo
Date: Thu Sep  9 18:10:18 2010
New Revision: 76976

Added:
   pypy/branch/jit-bounds/pypy/translator/c/gcc/test/elf64/
      - copied from r76975, pypy/trunk/pypy/translator/c/gcc/test/elf64/
Modified:
   pypy/branch/jit-bounds/   (props changed)
   pypy/branch/jit-bounds/pypy/config/translationoption.py
   pypy/branch/jit-bounds/pypy/jit/backend/llsupport/gc.py
   pypy/branch/jit-bounds/pypy/jit/backend/llsupport/test/test_gc.py
   pypy/branch/jit-bounds/pypy/jit/backend/test/runner_test.py
   pypy/branch/jit-bounds/pypy/jit/backend/x86/assembler.py
   pypy/branch/jit-bounds/pypy/jit/backend/x86/regalloc.py
   pypy/branch/jit-bounds/pypy/jit/backend/x86/regloc.py
   pypy/branch/jit-bounds/pypy/jit/backend/x86/rx86.py
   pypy/branch/jit-bounds/pypy/jit/backend/x86/test/test_gc_integration.py
   pypy/branch/jit-bounds/pypy/jit/backend/x86/test/test_zrpy_gc.py
   pypy/branch/jit-bounds/pypy/jit/backend/x86/test/test_ztranslation.py
   pypy/branch/jit-bounds/pypy/jit/metainterp/jitdriver.py
   pypy/branch/jit-bounds/pypy/jit/metainterp/optimizeopt/optimizer.py   (props changed)
   pypy/branch/jit-bounds/pypy/jit/metainterp/warmspot.py
   pypy/branch/jit-bounds/pypy/module/_ssl/interp_ssl.py
   pypy/branch/jit-bounds/pypy/module/_winreg/interp_winreg.py
   pypy/branch/jit-bounds/pypy/module/array/benchmark/Makefile   (props changed)
   pypy/branch/jit-bounds/pypy/module/array/benchmark/intimg.c   (props changed)
   pypy/branch/jit-bounds/pypy/module/array/benchmark/intimgtst.c   (props changed)
   pypy/branch/jit-bounds/pypy/module/array/benchmark/intimgtst.py   (props changed)
   pypy/branch/jit-bounds/pypy/module/array/benchmark/loop.c   (props changed)
   pypy/branch/jit-bounds/pypy/module/array/benchmark/sum.c   (props changed)
   pypy/branch/jit-bounds/pypy/module/array/benchmark/sumtst.c   (props changed)
   pypy/branch/jit-bounds/pypy/module/array/benchmark/sumtst.py   (props changed)
   pypy/branch/jit-bounds/pypy/module/array/test/test_array_old.py   (props changed)
   pypy/branch/jit-bounds/pypy/module/pypyjit/test/test_pypy_c.py
   pypy/branch/jit-bounds/pypy/objspace/flow/specialcase.py
   pypy/branch/jit-bounds/pypy/rlib/rmmap.py
   pypy/branch/jit-bounds/pypy/rlib/rsha.py
   pypy/branch/jit-bounds/pypy/rlib/rwin32.py
   pypy/branch/jit-bounds/pypy/rlib/rzipfile.py
   pypy/branch/jit-bounds/pypy/rpython/lltypesystem/rffi.py
   pypy/branch/jit-bounds/pypy/rpython/lltypesystem/test/test_rffi.py
   pypy/branch/jit-bounds/pypy/rpython/memory/gctransform/asmgcroot.py
   pypy/branch/jit-bounds/pypy/rpython/memory/gctypelayout.py
   pypy/branch/jit-bounds/pypy/rpython/module/ll_os.py
   pypy/branch/jit-bounds/pypy/rpython/module/ll_os_stat.py
   pypy/branch/jit-bounds/pypy/rpython/module/ll_win32file.py
   pypy/branch/jit-bounds/pypy/rpython/test/test_rint.py
   pypy/branch/jit-bounds/pypy/rpython/tool/rffi_platform.py
   pypy/branch/jit-bounds/pypy/rpython/tool/test/test_rffi_platform.py
   pypy/branch/jit-bounds/pypy/translator/c/database.py
   pypy/branch/jit-bounds/pypy/translator/c/gcc/instruction.py
   pypy/branch/jit-bounds/pypy/translator/c/gcc/test/conftest.py
   pypy/branch/jit-bounds/pypy/translator/c/gcc/test/test_trackgcroot.py
   pypy/branch/jit-bounds/pypy/translator/c/gcc/trackgcroot.py
   pypy/branch/jit-bounds/pypy/translator/platform/linux.py
   pypy/branch/jit-bounds/pypy/translator/platform/posix.py
Log:
svn merge -r76924:r76975 svn+ssh://hakanardo@codespeak.net/svn/pypy/trunk

Modified: pypy/branch/jit-bounds/pypy/config/translationoption.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/config/translationoption.py	(original)
+++ pypy/branch/jit-bounds/pypy/config/translationoption.py	Thu Sep  9 18:10:18 2010
@@ -343,11 +343,7 @@
     }
 
 def final_check_config(config):
-    # For now, 64-bit JIT requires boehm.  You have to say it explicitly
-    # with --gc=boehm, so that you don't get boehm by mistake.
-    if IS_64_BITS:
-        if config.translation.jit and config.translation.gc != 'boehm':
-            raise ConfigError("for now, 64-bit JIT requires --gc=boehm")
+    pass
 
 def set_opt_level(config, level):
     """Apply optimization suggestions on the 'config'.

Modified: pypy/branch/jit-bounds/pypy/jit/backend/llsupport/gc.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/jit/backend/llsupport/gc.py	(original)
+++ pypy/branch/jit-bounds/pypy/jit/backend/llsupport/gc.py	Thu Sep  9 18:10:18 2010
@@ -251,13 +251,25 @@
         if oldgcmap:
             lltype.free(oldgcmap, flavor='raw')
 
-    def get_basic_shape(self):
-        return [chr(self.LOC_EBP_PLUS  | 4),    # return addr: at   4(%ebp)
-                chr(self.LOC_EBP_MINUS | 4),    # saved %ebx:  at  -4(%ebp)
-                chr(self.LOC_EBP_MINUS | 8),    # saved %esi:  at  -8(%ebp)
-                chr(self.LOC_EBP_MINUS | 12),   # saved %edi:  at -12(%ebp)
-                chr(self.LOC_EBP_PLUS  | 0),    # saved %ebp:  at    (%ebp)
-                chr(0)]
+    def get_basic_shape(self, is_64_bit=False):
+        # XXX: Should this code even really know about stack frame layout of
+        # the JIT?
+        if is_64_bit:
+            return [chr(self.LOC_EBP_PLUS  | 8),
+                    chr(self.LOC_EBP_MINUS | 8),
+                    chr(self.LOC_EBP_MINUS | 16),
+                    chr(self.LOC_EBP_MINUS | 24),
+                    chr(self.LOC_EBP_MINUS | 32),
+                    chr(self.LOC_EBP_MINUS | 40),
+                    chr(self.LOC_EBP_PLUS  | 0),
+                    chr(0)]
+        else:
+            return [chr(self.LOC_EBP_PLUS  | 4),    # return addr: at   4(%ebp)
+                    chr(self.LOC_EBP_MINUS | 4),    # saved %ebx:  at  -4(%ebp)
+                    chr(self.LOC_EBP_MINUS | 8),    # saved %esi:  at  -8(%ebp)
+                    chr(self.LOC_EBP_MINUS | 12),   # saved %edi:  at -12(%ebp)
+                    chr(self.LOC_EBP_PLUS  | 0),    # saved %ebp:  at    (%ebp)
+                    chr(0)]
 
     def _encode_num(self, shape, number):
         assert number >= 0
@@ -276,17 +288,9 @@
             num = self.LOC_EBP_MINUS | (-offset)
         self._encode_num(shape, num)
 
-    def add_ebx(self, shape):
-        shape.append(chr(self.LOC_REG | 4))
-
-    def add_esi(self, shape):
-        shape.append(chr(self.LOC_REG | 8))
-
-    def add_edi(self, shape):
-        shape.append(chr(self.LOC_REG | 12))
-
-    def add_ebp(self, shape):
-        shape.append(chr(self.LOC_REG | 16))
+    def add_callee_save_reg(self, shape, reg_index):
+        assert reg_index > 0
+        shape.append(chr(self.LOC_REG | (reg_index << 2)))
 
     def compress_callshape(self, shape):
         # Similar to compress_callshape() in trackgcroot.py.

Modified: pypy/branch/jit-bounds/pypy/jit/backend/llsupport/test/test_gc.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/jit/backend/llsupport/test/test_gc.py	(original)
+++ pypy/branch/jit-bounds/pypy/jit/backend/llsupport/test/test_gc.py	Thu Sep  9 18:10:18 2010
@@ -73,16 +73,16 @@
     gcrootmap.add_ebp_offset(shape, num1)
     gcrootmap.add_ebp_offset(shape, num2)
     assert shape == map(chr, [6, 7, 11, 15, 2, 0, num1a, num2b, num2a])
-    gcrootmap.add_ebx(shape)
+    gcrootmap.add_callee_save_reg(shape, 1)
     assert shape == map(chr, [6, 7, 11, 15, 2, 0, num1a, num2b, num2a,
                               4])
-    gcrootmap.add_esi(shape)
+    gcrootmap.add_callee_save_reg(shape, 2)
     assert shape == map(chr, [6, 7, 11, 15, 2, 0, num1a, num2b, num2a,
                               4, 8])
-    gcrootmap.add_edi(shape)
+    gcrootmap.add_callee_save_reg(shape, 3)
     assert shape == map(chr, [6, 7, 11, 15, 2, 0, num1a, num2b, num2a,
                               4, 8, 12])
-    gcrootmap.add_ebp(shape)
+    gcrootmap.add_callee_save_reg(shape, 4)
     assert shape == map(chr, [6, 7, 11, 15, 2, 0, num1a, num2b, num2a,
                               4, 8, 12, 16])
     #

Modified: pypy/branch/jit-bounds/pypy/jit/backend/test/runner_test.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/jit/backend/test/runner_test.py	(original)
+++ pypy/branch/jit-bounds/pypy/jit/backend/test/runner_test.py	Thu Sep  9 18:10:18 2010
@@ -1777,7 +1777,7 @@
         self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
         ARGS = [lltype.Signed] * 10
         RES = lltype.Signed
-        self.cpu.portal_calldescr = self.cpu.calldescrof(
+        FakeJitDriverSD.portal_calldescr = self.cpu.calldescrof(
             lltype.Ptr(lltype.FuncType(ARGS, RES)), ARGS, RES)
         for i in range(10):
             self.cpu.set_future_value_int(i, i+1)
@@ -1816,7 +1816,7 @@
 
         ARGS = [lltype.Float, lltype.Float]
         RES = lltype.Float
-        self.cpu.portal_calldescr = self.cpu.calldescrof(
+        FakeJitDriverSD.portal_calldescr = self.cpu.calldescrof(
             lltype.Ptr(lltype.FuncType(ARGS, RES)), ARGS, RES)
         
         ops = '''

Modified: pypy/branch/jit-bounds/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/jit/backend/x86/assembler.py	(original)
+++ pypy/branch/jit-bounds/pypy/jit/backend/x86/assembler.py	Thu Sep  9 18:10:18 2010
@@ -273,7 +273,8 @@
         if IS_X86_32:
             self.mc.MOV_sr(WORD, edx.value)        # save it as the new argument
         elif IS_X86_64:
-            # FIXME: We can't just clobber rdi like this, can we?
+            # rdi can be clobbered: its content was forced to the stack
+            # by _fastpath_malloc(), like all other save_around_call_regs.
             self.mc.MOV_rr(edi.value, edx.value)
 
         addr = self.cpu.gc_ll_descr.get_malloc_fixedsize_slowpath_addr()
@@ -1256,8 +1257,12 @@
             sizeof_ti = rffi.sizeof(GCData.TYPE_INFO)
             type_info_group = llop.gc_get_type_info_group(llmemory.Address)
             type_info_group = rffi.cast(lltype.Signed, type_info_group)
-            expected_typeid = (classptr - sizeof_ti - type_info_group) >> 2
-            self.mc.CMP16(mem(locs[0], 0), ImmedLoc(expected_typeid))
+            expected_typeid = classptr - sizeof_ti - type_info_group
+            if IS_X86_32:
+                expected_typeid >>= 2
+                self.mc.CMP16(mem(locs[0], 0), ImmedLoc(expected_typeid))
+            elif IS_X86_64:
+                self.mc.CMP32_mi((locs[0].value, 0), expected_typeid)
 
     def genop_guard_guard_class(self, ign_1, guard_op, guard_token, locs, ign_2):
         self.mc.ensure_bytes_available(256)

Modified: pypy/branch/jit-bounds/pypy/jit/backend/x86/regalloc.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/jit/backend/x86/regalloc.py	(original)
+++ pypy/branch/jit-bounds/pypy/jit/backend/x86/regalloc.py	Thu Sep  9 18:10:18 2010
@@ -26,6 +26,12 @@
     no_lower_byte_regs = [esi, edi]
     save_around_call_regs = [eax, edx, ecx]
 
+    REGLOC_TO_GCROOTMAP_REG_INDEX = {
+        ebx: 1,
+        esi: 2,
+        edi: 3,
+    }
+
     def call_result_location(self, v):
         return eax
 
@@ -47,6 +53,13 @@
     no_lower_byte_regs = []
     save_around_call_regs = [eax, ecx, edx, esi, edi, r8, r9, r10]
 
+    REGLOC_TO_GCROOTMAP_REG_INDEX = {
+        ebx: 1,
+        r12: 2,
+        r13: 3,
+        r14: 4,
+        r15: 5,
+    }
 
 class FloatConstants(object):
     BASE_CONSTANT_SIZE = 1000
@@ -652,13 +665,11 @@
         self._consider_call(op, guard_op)
 
     def consider_call_assembler(self, op, guard_op):
-        portal_calldescr = self.assembler.cpu.portal_calldescr
-        size = portal_calldescr.get_result_size(self.translate_support_code)
-        #
         descr = op.descr
         assert isinstance(descr, LoopToken)
         jd = descr.outermost_jitdriver_sd
         assert jd is not None
+        size = jd.portal_calldescr.get_result_size(self.translate_support_code)
         vable_index = jd.index_of_virtualizable
         if vable_index >= 0:
             self.rm._sync_var(op.args[vable_index])
@@ -694,23 +705,18 @@
     def _fastpath_malloc(self, op, descr):
         assert isinstance(descr, BaseSizeDescr)
         gc_ll_descr = self.assembler.cpu.gc_ll_descr
-        tmp0 = TempBox()
         self.rm.force_allocate_reg(op.result, selected_reg=eax)
-        self.rm.force_allocate_reg(tmp0, selected_reg=edx)
-        # XXX about the next 10 lines: why not just say
-        #      force_allocate_reg(tmp1, selected_reg=ecx)?????
-        for v, reg in self.rm.reg_bindings.items():
-            if reg is ecx:
-                to_sync = v
-                break
-        else:
-            to_sync = None
-        if to_sync is not None:
-            self.rm._sync_var(to_sync)
-            del self.rm.reg_bindings[to_sync]
-            self.rm.free_regs.append(ecx)
-        # we need to do it here, so edx is not in reg_bindings
-        self.rm.possibly_free_var(tmp0)
+        # We need to force-allocate each of save_around_call_regs now.
+        # The alternative would be to save and restore them around the
+        # actual call to malloc(), in the rare case where we need to do
+        # it; however, mark_gc_roots() would need to be adapted to know
+        # where the variables end up being saved.  Messy.
+        for reg in self.rm.save_around_call_regs:
+            if reg is not eax:
+                tmp_box = TempBox()
+                self.rm.force_allocate_reg(tmp_box, selected_reg=reg)
+                self.rm.possibly_free_var(tmp_box)
+
         self.assembler.malloc_cond_fixedsize(
             gc_ll_descr.get_nursery_free_addr(),
             gc_ll_descr.get_nursery_top_addr(),
@@ -962,7 +968,7 @@
         pass
 
     def get_mark_gc_roots(self, gcrootmap):
-        shape = gcrootmap.get_basic_shape()
+        shape = gcrootmap.get_basic_shape(IS_X86_64)
         for v, val in self.fm.frame_bindings.items():
             if (isinstance(v, BoxPtr) and self.rm.stays_alive(v)):
                 assert isinstance(val, StackLoc)
@@ -971,15 +977,8 @@
             if reg is eax:
                 continue      # ok to ignore this one
             if (isinstance(v, BoxPtr) and self.rm.stays_alive(v)):
-                if reg is ebx:
-                    gcrootmap.add_ebx(shape)
-                elif reg is esi:
-                    gcrootmap.add_esi(shape)
-                elif reg is edi:
-                    gcrootmap.add_edi(shape)
-                else:
-                    print "[get_mark_gc_roots] bogus register", reg
-                    assert False
+                assert reg in self.rm.REGLOC_TO_GCROOTMAP_REG_INDEX
+                gcrootmap.add_callee_save_reg(shape, self.rm.REGLOC_TO_GCROOTMAP_REG_INDEX[reg])
         return gcrootmap.compress_callshape(shape)
 
     def consider_force_token(self, op):

Modified: pypy/branch/jit-bounds/pypy/jit/backend/x86/regloc.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/jit/backend/x86/regloc.py	(original)
+++ pypy/branch/jit-bounds/pypy/jit/backend/x86/regloc.py	Thu Sep  9 18:10:18 2010
@@ -1,7 +1,7 @@
 from pypy.jit.metainterp.history import AbstractValue, ConstInt
 from pypy.jit.backend.x86 import rx86
 from pypy.rlib.unroll import unrolling_iterable
-from pypy.jit.backend.x86.arch import WORD
+from pypy.jit.backend.x86.arch import WORD, IS_X86_32, IS_X86_64
 from pypy.tool.sourcetools import func_with_new_name
 from pypy.rlib.objectmodel import specialize
 from pypy.rlib.rarithmetic import intmask

Modified: pypy/branch/jit-bounds/pypy/jit/backend/x86/rx86.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/jit/backend/x86/rx86.py	(original)
+++ pypy/branch/jit-bounds/pypy/jit/backend/x86/rx86.py	Thu Sep  9 18:10:18 2010
@@ -462,6 +462,8 @@
     CMP_ji = select_8_or_32_bit_immed(CMP_ji8, CMP_ji32)
     CMP_rj = insn(rex_w, '\x3B', register(1, 8), '\x05', immediate(2))
 
+    CMP32_mi = insn(rex_nw, '\x81', orbyte(7<<3), mem_reg_plus_const(1), immediate(2))
+
     AND8_rr = insn(rex_w, '\x20', byte_register(1), byte_register(2,8), '\xC0')
 
     OR8_rr = insn(rex_w, '\x08', byte_register(1), byte_register(2,8), '\xC0')

Modified: pypy/branch/jit-bounds/pypy/jit/backend/x86/test/test_gc_integration.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/jit/backend/x86/test/test_gc_integration.py	(original)
+++ pypy/branch/jit-bounds/pypy/jit/backend/x86/test/test_gc_integration.py	Thu Sep  9 18:10:18 2010
@@ -26,16 +26,13 @@
 CPU = getcpuclass()
 
 class MockGcRootMap(object):
-    def get_basic_shape(self):
+    def get_basic_shape(self, is_64_bit):
         return ['shape']
     def add_ebp_offset(self, shape, offset):
         shape.append(offset)
-    def add_ebx(self, shape):
-        shape.append('ebx')
-    def add_esi(self, shape):
-        shape.append('esi')
-    def add_edi(self, shape):
-        shape.append('edi')
+    def add_callee_save_reg(self, shape, reg_index):
+        index_to_name = { 1: 'ebx', 2: 'esi', 3: 'edi' }
+        shape.append(index_to_name[reg_index])
     def compress_callshape(self, shape):
         assert shape[0] == 'shape'
         return ['compressed'] + shape[1:]

Modified: pypy/branch/jit-bounds/pypy/jit/backend/x86/test/test_zrpy_gc.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/jit/backend/x86/test/test_zrpy_gc.py	(original)
+++ pypy/branch/jit-bounds/pypy/jit/backend/x86/test/test_zrpy_gc.py	Thu Sep  9 18:10:18 2010
@@ -128,10 +128,6 @@
 
 class TestCompileHybrid(object):
     def setup_class(cls):
-        if IS_X86_64:
-            # No hybrid GC on 64-bit for the time being
-            py.test.skip()
-
         funcs = []
         name_to_func = {}
         for fullname in dir(cls):

Modified: pypy/branch/jit-bounds/pypy/jit/backend/x86/test/test_ztranslation.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/jit/backend/x86/test/test_ztranslation.py	(original)
+++ pypy/branch/jit-bounds/pypy/jit/backend/x86/test/test_ztranslation.py	Thu Sep  9 18:10:18 2010
@@ -125,10 +125,6 @@
         return t
 
     def test_external_exception_handling_translates(self):
-        # FIXME
-        if IS_X86_64:
-            import py.test; py.test.skip()
-
         jitdriver = JitDriver(greens = [], reds = ['n', 'total'])
 
         class ImDone(Exception):

Modified: pypy/branch/jit-bounds/pypy/jit/metainterp/jitdriver.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/jit/metainterp/jitdriver.py	(original)
+++ pypy/branch/jit-bounds/pypy/jit/metainterp/jitdriver.py	Thu Sep  9 18:10:18 2010
@@ -8,6 +8,7 @@
     #    self.portal_graph      ... pypy.jit.metainterp.warmspot
     #    self.portal_runner_ptr ... pypy.jit.metainterp.warmspot
     #    self.portal_runner_adr ... pypy.jit.metainterp.warmspot
+    #    self.portal_calldescr  ... pypy.jit.metainterp.warmspot
     #    self.num_green_args    ... pypy.jit.metainterp.warmspot
     #    self.result_type       ... pypy.jit.metainterp.warmspot
     #    self.virtualizable_info... pypy.jit.metainterp.warmspot

Modified: pypy/branch/jit-bounds/pypy/jit/metainterp/warmspot.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/jit/metainterp/warmspot.py	(original)
+++ pypy/branch/jit-bounds/pypy/jit/metainterp/warmspot.py	Thu Sep  9 18:10:18 2010
@@ -648,7 +648,7 @@
         jd.portal_runner_ptr = self.helper_func(jd._PTR_PORTAL_FUNCTYPE,
                                                 ll_portal_runner)
         jd.portal_runner_adr = llmemory.cast_ptr_to_adr(jd.portal_runner_ptr)
-        self.cpu.portal_calldescr = self.cpu.calldescrof(
+        jd.portal_calldescr = self.cpu.calldescrof(
             jd._PTR_PORTAL_FUNCTYPE.TO,
             jd._PTR_PORTAL_FUNCTYPE.TO.ARGS,
             jd._PTR_PORTAL_FUNCTYPE.TO.RESULT)

Modified: pypy/branch/jit-bounds/pypy/module/_ssl/interp_ssl.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/module/_ssl/interp_ssl.py	(original)
+++ pypy/branch/jit-bounds/pypy/module/_ssl/interp_ssl.py	Thu Sep  9 18:10:18 2010
@@ -18,6 +18,9 @@
         # need of winsock2.  Remove this when separate compilation is
         # available...
         'winsock2.h',
+        # wincrypt.h defines X509_NAME, include it here
+        # so that openssl/ssl.h can repair this nonsense.
+        'wincrypt.h',
         'openssl/ssl.h',
         'openssl/err.h']
 else:
@@ -88,18 +91,12 @@
     globals()[k] = v
 
 # opaque structures
-SSL_METHOD = rffi.VOIDP
-SSL_CTX = rffi.VOIDP
-SSL = rffi.VOIDP
-BIO = rffi.VOIDP
-X509 = rffi.VOIDP
-X509_NAME = rffi.VOIDP
-
-SSL_CTX_P = rffi.CArrayPtr(SSL_CTX)
-BIO_P = rffi.CArrayPtr(BIO)
-SSL_P = rffi.CArrayPtr(SSL)
-X509_P = rffi.CArrayPtr(X509)
-X509_NAME_P = rffi.CArrayPtr(X509_NAME)
+SSL_METHOD = rffi.COpaquePtr('SSL_METHOD')
+SSL_CTX = rffi.COpaquePtr('SSL_CTX')
+SSL = rffi.COpaquePtr('SSL')
+BIO = rffi.COpaquePtr('BIO')
+X509 = rffi.COpaquePtr('X509')
+X509_NAME = rffi.COpaquePtr('X509_NAME')
 
 HAVE_OPENSSL_RAND = OPENSSL_VERSION_NUMBER >= 0x0090500f
 
@@ -125,33 +122,33 @@
     ssl_external('RAND_add', [rffi.CCHARP, rffi.INT, rffi.DOUBLE], lltype.Void)
     ssl_external('RAND_status', [], rffi.INT)
     ssl_external('RAND_egd', [rffi.CCHARP], rffi.INT)
-ssl_external('SSL_CTX_new', [rffi.CArrayPtr(SSL_METHOD)], SSL_CTX_P)
-ssl_external('SSLv23_method', [], rffi.CArrayPtr(SSL_METHOD))
-ssl_external('SSL_CTX_use_PrivateKey_file', [SSL_CTX_P, rffi.CCHARP, rffi.INT], rffi.INT)
-ssl_external('SSL_CTX_use_certificate_chain_file', [SSL_CTX_P, rffi.CCHARP], rffi.INT)
-ssl_external('SSL_CTX_ctrl', [SSL_CTX_P, rffi.INT, rffi.INT, rffi.VOIDP], rffi.INT)
-ssl_external('SSL_CTX_set_verify', [SSL_CTX_P, rffi.INT, rffi.VOIDP], lltype.Void)
-ssl_external('SSL_new', [SSL_CTX_P], SSL_P)
-ssl_external('SSL_set_fd', [SSL_P, rffi.INT], rffi.INT)
-ssl_external('BIO_ctrl', [BIO_P, rffi.INT, rffi.INT, rffi.VOIDP], rffi.INT)
-ssl_external('SSL_get_rbio', [SSL_P], BIO_P)
-ssl_external('SSL_get_wbio', [SSL_P], BIO_P)
-ssl_external('SSL_set_connect_state', [SSL_P], lltype.Void)
-ssl_external('SSL_connect', [SSL_P], rffi.INT)
-ssl_external('SSL_get_error', [SSL_P, rffi.INT], rffi.INT)
+ssl_external('SSL_CTX_new', [SSL_METHOD], SSL_CTX)
+ssl_external('SSLv23_method', [], SSL_METHOD)
+ssl_external('SSL_CTX_use_PrivateKey_file', [SSL_CTX, rffi.CCHARP, rffi.INT], rffi.INT)
+ssl_external('SSL_CTX_use_certificate_chain_file', [SSL_CTX, rffi.CCHARP], rffi.INT)
+ssl_external('SSL_CTX_ctrl', [SSL_CTX, rffi.INT, rffi.INT, rffi.VOIDP], rffi.INT)
+ssl_external('SSL_CTX_set_verify', [SSL_CTX, rffi.INT, rffi.VOIDP], lltype.Void)
+ssl_external('SSL_new', [SSL_CTX], SSL)
+ssl_external('SSL_set_fd', [SSL, rffi.INT], rffi.INT)
+ssl_external('BIO_ctrl', [BIO, rffi.INT, rffi.INT, rffi.VOIDP], rffi.INT)
+ssl_external('SSL_get_rbio', [SSL], BIO)
+ssl_external('SSL_get_wbio', [SSL], BIO)
+ssl_external('SSL_set_connect_state', [SSL], lltype.Void)
+ssl_external('SSL_connect', [SSL], rffi.INT)
+ssl_external('SSL_get_error', [SSL, rffi.INT], rffi.INT)
 
 ssl_external('ERR_get_error', [], rffi.INT)
 ssl_external('ERR_error_string', [rffi.ULONG, rffi.CCHARP], rffi.CCHARP)
-ssl_external('SSL_get_peer_certificate', [SSL_P], X509_P)
-ssl_external('X509_get_subject_name', [X509_P], X509_NAME_P)
-ssl_external('X509_get_issuer_name', [X509_P], X509_NAME_P)
-ssl_external('X509_NAME_oneline', [X509_NAME_P, rffi.CCHARP, rffi.INT], rffi.CCHARP)
-ssl_external('X509_free', [X509_P], lltype.Void)
-ssl_external('SSL_free', [SSL_P], lltype.Void)
-ssl_external('SSL_CTX_free', [SSL_CTX_P], lltype.Void)
-ssl_external('SSL_write', [SSL_P, rffi.CCHARP, rffi.INT], rffi.INT)
-ssl_external('SSL_pending', [SSL_P], rffi.INT)
-ssl_external('SSL_read', [SSL_P, rffi.CCHARP, rffi.INT], rffi.INT)
+ssl_external('SSL_get_peer_certificate', [SSL], X509)
+ssl_external('X509_get_subject_name', [X509], X509_NAME)
+ssl_external('X509_get_issuer_name', [X509], X509_NAME)
+ssl_external('X509_NAME_oneline', [X509_NAME, rffi.CCHARP, rffi.INT], rffi.CCHARP)
+ssl_external('X509_free', [X509], lltype.Void)
+ssl_external('SSL_free', [SSL], lltype.Void)
+ssl_external('SSL_CTX_free', [SSL_CTX], lltype.Void)
+ssl_external('SSL_write', [SSL, rffi.CCHARP, rffi.INT], rffi.INT)
+ssl_external('SSL_pending', [SSL], rffi.INT)
+ssl_external('SSL_read', [SSL, rffi.CCHARP, rffi.INT], rffi.INT)
 
 def ssl_error(space, msg):
     w_module = space.getbuiltinmodule('_ssl')
@@ -212,9 +209,9 @@
     def __init__(self, space):
         self.space = space
         self.w_socket = None
-        self.ctx = lltype.nullptr(SSL_CTX_P.TO)
-        self.ssl = lltype.nullptr(SSL_P.TO)
-        self.server_cert = lltype.nullptr(X509_P.TO)
+        self.ctx = lltype.nullptr(SSL_CTX.TO)
+        self.ssl = lltype.nullptr(SSL.TO)
+        self.server_cert = lltype.nullptr(X509.TO)
         self._server = lltype.malloc(rffi.CCHARP.TO, X509_NAME_MAXLEN, flavor='raw')
         self._server[0] = '\0'
         self._issuer = lltype.malloc(rffi.CCHARP.TO, X509_NAME_MAXLEN, flavor='raw')

Modified: pypy/branch/jit-bounds/pypy/module/_winreg/interp_winreg.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/module/_winreg/interp_winreg.py	(original)
+++ pypy/branch/jit-bounds/pypy/module/_winreg/interp_winreg.py	Thu Sep  9 18:10:18 2010
@@ -20,16 +20,19 @@
         self.Close(space)
     descr_del.unwrap_spec = ['self', ObjSpace]
 
+    def as_int(self):
+        return rffi.cast(rffi.SIZE_T, self.hkey)
+
     def descr_nonzero(self, space):
-        return space.wrap(self.hkey != 0)
+        return space.wrap(self.as_int() != 0)
     descr_nonzero.unwrap_spec = ['self', ObjSpace]
 
     def descr_repr(self, space):
-        return space.wrap("<PyHKEY:0x%x>" % (self.hkey,))
+        return space.wrap("<PyHKEY:0x%x>" % (self.as_int(),))
     descr_repr.unwrap_spec = ['self', ObjSpace]
 
     def descr_int(self, space):
-        return space.wrap(self.hkey)
+        return space.wrap(self.as_int())
     descr_int.unwrap_spec = ['self', ObjSpace]
 
     def Close(self, space):
@@ -49,12 +52,13 @@
 need the underlying win32 handle to exist beyond the lifetime of the
 handle object.
 On 64 bit windows, the result of this function is a long integer"""
-        hkey = self.hkey
-        self.hkey = 0
-        return space.wrap(hkey)
+        key = self.as_int()
+        self.hkey = rwin32.NULL_HANDLE
+        return space.wrap(key)
     Detach.unwrap_spec = ['self', ObjSpace]
 
-def new_HKEY(space, w_subtype, hkey):
+def new_HKEY(space, w_subtype, key):
+    hkey = rffi.cast(rwinreg.HKEY, key)
     return space.wrap(W_HKEY(hkey))
 descr_HKEY_new = interp2app(new_HKEY,
                             unwrap_spec=[ObjSpace, W_Root, int])
@@ -98,9 +102,9 @@
     elif isinstance(w_hkey, W_HKEY):
         return w_hkey.hkey
     elif space.is_true(space.isinstance(w_hkey, space.w_int)):
-        return space.int_w(w_hkey)
+        return rffi.cast(rwinreg.HKEY, space.int_w(w_hkey))
     elif space.is_true(space.isinstance(w_hkey, space.w_long)):
-        return space.uint_w(w_hkey)
+        return rffi.cast(rwinreg.HKEY, space.uint_w(w_hkey))
     else:
         errstring = space.wrap("The object is not a PyHKEY object")
         raise OperationError(space.w_TypeError, errstring)
@@ -631,8 +635,8 @@
                     null_dword, ft)
                 if ret != 0:
                     raiseWindowsError(space, ret, 'RegQueryInfoKey')
-                l = (ft[0].c_dwLowDateTime +
-                     (ft[0].c_dwHighDateTime << 32))
+                l = ((lltype.r_longlong(ft[0].c_dwHighDateTime) << 32) +
+                     lltype.r_longlong(ft[0].c_dwLowDateTime))
                 return space.newtuple([space.wrap(nSubKeys[0]),
                                        space.wrap(nValues[0]),
                                        space.wrap(l)])

Modified: pypy/branch/jit-bounds/pypy/module/pypyjit/test/test_pypy_c.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/module/pypyjit/test/test_pypy_c.py	(original)
+++ pypy/branch/jit-bounds/pypy/module/pypyjit/test/test_pypy_c.py	Thu Sep  9 18:10:18 2010
@@ -191,7 +191,7 @@
                 return r
         ''', 28,
                    ([5], 120),
-                    ([20], 2432902008176640000L))
+                    ([25], 15511210043330985984000000L))
 
     def test_factorialrec(self):
         self.run_source('''
@@ -202,7 +202,7 @@
                     return 1
         ''', 0,
                    ([5], 120),
-                    ([20], 2432902008176640000L))
+                    ([25], 15511210043330985984000000L))
 
     def test_richards(self):
         self.run_source('''

Modified: pypy/branch/jit-bounds/pypy/objspace/flow/specialcase.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/objspace/flow/specialcase.py	(original)
+++ pypy/branch/jit-bounds/pypy/objspace/flow/specialcase.py	Thu Sep  9 18:10:18 2010
@@ -3,6 +3,7 @@
 from pypy.interpreter.gateway import ApplevelClass
 from pypy.interpreter.error import OperationError
 from pypy.tool.cache import Cache
+from pypy.rlib.rarithmetic import r_uint
 import py
 
 def sc_import(space, fn, args):
@@ -120,6 +121,14 @@
         pass
     return space.do_operation('simple_call', Constant(func), *args_w)
 
+def sc_r_uint(space, r_uint, args):
+    args_w, kwds_w = args.unpack()
+    assert not kwds_w
+    [w_value] = args_w
+    if isinstance(w_value, Constant):
+        return Constant(r_uint(w_value.value))
+    return space.do_operation('simple_call', space.wrap(r_uint), w_value)
+
 def setup(space):
     # fn = pyframe.normalize_exception.get_function(space)
     # this is now routed through the objspace, directly.
@@ -131,3 +140,7 @@
     # if possible
     for fn in OperationName:
         space.specialcases[fn] = sc_operator
+    # special case to constant-fold r_uint(32-bit-constant)
+    # (normally, the 32-bit constant is a long, and is not allowed to
+    # show up in the flow graphs at all)
+    space.specialcases[r_uint] = sc_r_uint

Modified: pypy/branch/jit-bounds/pypy/rlib/rmmap.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/rlib/rmmap.py	(original)
+++ pypy/branch/jit-bounds/pypy/rlib/rmmap.py	Thu Sep  9 18:10:18 2010
@@ -72,6 +72,7 @@
         setattr(CConfig, name, rffi_platform.ConstantInteger(name))
 
     from pypy.rlib.rwin32 import HANDLE, LPHANDLE
+    from pypy.rlib.rwin32 import NULL_HANDLE, INVALID_HANDLE_VALUE
     from pypy.rlib.rwin32 import DWORD, WORD, DWORD_PTR, LPDWORD
     from pypy.rlib.rwin32 import BOOL, LPVOID, LPCVOID, LPCSTR, SIZE_T
     from pypy.rlib.rwin32 import INT, LONG, PLONG
@@ -183,7 +184,7 @@
     ##_get_osfhandle = winexternal('_get_osfhandle', [INT], LONG)
     # casting from int to handle did not work, so I changed this
     # but it should not be so!
-    _get_osfhandle = winexternal('_get_osfhandle', [INT], HANDLE)
+    _get_osfhandle = winexternal('_get_osfhandle', [INT], rffi.INTPTR_T)
     GetLastError = winexternal('GetLastError', [], DWORD)
     VirtualAlloc = winexternal('VirtualAlloc',
                                [rffi.VOIDP, rffi.SIZE_T, DWORD, DWORD],
@@ -228,8 +229,7 @@
     def _get_error_no():
         return rffi.cast(lltype.Signed, GetLastError())
 
-    NULL_HANDLE = rffi.cast(HANDLE, 0)
-    INVALID_HANDLE = rffi.cast(HANDLE, -1)
+    INVALID_HANDLE = INVALID_HANDLE_VALUE
 
 PAGESIZE = _get_page_size()
 NULL = lltype.nullptr(PTR.TO)
@@ -684,12 +684,11 @@
         # assume -1 and 0 both mean invalid file descriptor
         # to 'anonymously' map memory.
         if fileno != -1 and fileno != 0:
-            fh = _get_osfhandle(fileno)
-            # parts of the C library use HANDLE, others just ints
-            # XXX hack - made _get_osfhandle compatible
-            if fh == INVALID_HANDLE:
+            res = _get_osfhandle(fileno)
+            if res == rffi.cast(rffi.SSIZE_T, INVALID_HANDLE):
                 errno = _get_error_no()
                 raise OSError(errno, os.strerror(errno))
+            fh = rffi.cast(HANDLE, res)
             # Win9x appears to need us seeked to zero
             # SEEK_SET = 0
             # libc._lseek(fileno, 0, SEEK_SET)

Modified: pypy/branch/jit-bounds/pypy/rlib/rsha.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/rlib/rsha.py	(original)
+++ pypy/branch/jit-bounds/pypy/rlib/rsha.py	Thu Sep  9 18:10:18 2010
@@ -88,7 +88,7 @@
     0xCA62C1D6L  # (60 <= t <= 79)
     ]
 
-unroll_f_K = unrolling_iterable(zip(f, K))
+unroll_f_K = unrolling_iterable(zip(f, map(r_uint, K)))
 if UNROLL_ALL:
     unroll_range_20 = unrolling_iterable(range(20))
 

Modified: pypy/branch/jit-bounds/pypy/rlib/rwin32.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/rlib/rwin32.py	(original)
+++ pypy/branch/jit-bounds/pypy/rlib/rwin32.py	Thu Sep  9 18:10:18 2010
@@ -81,9 +81,10 @@
     return rffi.llexternal(name, args, result, compilation_info=eci, calling_conv='win')
 
 if WIN32:
-    HANDLE = rffi.ULONG
+    HANDLE = rffi.COpaquePtr(typedef='HANDLE')
     LPHANDLE = rffi.CArrayPtr(HANDLE)
     HMODULE = HANDLE
+    NULL_HANDLE = rffi.cast(HANDLE, 0)
     INVALID_HANDLE_VALUE = rffi.cast(HANDLE, -1)
     PFILETIME = rffi.CArrayPtr(FILETIME)
 

Modified: pypy/branch/jit-bounds/pypy/rlib/rzipfile.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/rlib/rzipfile.py	(original)
+++ pypy/branch/jit-bounds/pypy/rlib/rzipfile.py	Thu Sep  9 18:10:18 2010
@@ -19,12 +19,12 @@
 
 def crc32(s, crc=0):
     result = 0
-    crc = ~r_uint(crc) & 0xffffffffL
+    crc = ~r_uint(crc) & r_uint(0xffffffffL)
     for c in s:
         crc = rcrc_32_tab[(crc ^ r_uint(ord(c))) & 0xffL] ^ (crc >> 8)
         #/* Note:  (crc >> 8) MUST zero fill on left
 
-        result = crc ^ 0xffffffffL
+        result = crc ^ r_uint(0xffffffffL)
     
     return result
 
@@ -194,7 +194,7 @@
             (x.create_version, x.create_system, x.extract_version, x.reserved,
                 x.flag_bits, x.compress_type, t, d,
                 crc, x.compress_size, x.file_size) = centdir[1:12]
-            x.CRC = r_uint(crc) & 0xffffffff
+            x.CRC = r_uint(crc) & r_uint(0xffffffff)
             x.dostime = t
             x.dosdate = d
             x.volume, x.internal_attr, x.external_attr = centdir[15:18]

Modified: pypy/branch/jit-bounds/pypy/rpython/lltypesystem/rffi.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/rpython/lltypesystem/rffi.py	(original)
+++ pypy/branch/jit-bounds/pypy/rpython/lltypesystem/rffi.py	Thu Sep  9 18:10:18 2010
@@ -358,9 +358,11 @@
 if os.name != 'nt':
     TYPES.append('mode_t')
     TYPES.append('pid_t')
+    TYPES.append('ssize_t')
 else:
     MODE_T = lltype.Signed
     PID_T = lltype.Signed
+    SSIZE_T = lltype.Signed
 
 def populate_inttypes():
     names = []
@@ -415,6 +417,7 @@
 #        ULONGLONG      r_ulonglong
 #        WCHAR_T        r_wchar_t
 #        SIZE_T         r_size_t
+#        SSIZE_T        r_ssize_t
 #        TIME_T         r_time_t
 # --------------------------------------------------------------------
 # Note that rffi.r_int is not necessarily the same as
@@ -535,6 +538,8 @@
 # (use SIGNEDCHAR or UCHAR for the small integer types)
 CHAR = lltype.Char
 
+INTPTR_T = SSIZE_T
+
 # double
 DOUBLE = lltype.Float
 

Modified: pypy/branch/jit-bounds/pypy/rpython/lltypesystem/test/test_rffi.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/rpython/lltypesystem/test/test_rffi.py	(original)
+++ pypy/branch/jit-bounds/pypy/rpython/lltypesystem/test/test_rffi.py	Thu Sep  9 18:10:18 2010
@@ -186,6 +186,11 @@
     
     def test_externvar(self):
         import os
+        if os.name == 'nt':
+            # Windows CRT badly aborts when an invalid fd is used.
+            bad_fd = 0
+        else:
+            bad_fd = 12312312
     
         def f():
             set_errno(12)
@@ -193,7 +198,7 @@
     
         def g():
             try:
-                os.write(12312312, "xxx")
+                os.write(bad_fd, "xxx")
             except OSError:
                 pass
             return get_errno()

Modified: pypy/branch/jit-bounds/pypy/rpython/memory/gctransform/asmgcroot.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/rpython/memory/gctransform/asmgcroot.py	(original)
+++ pypy/branch/jit-bounds/pypy/rpython/memory/gctransform/asmgcroot.py	Thu Sep  9 18:10:18 2010
@@ -18,6 +18,7 @@
 #  The .s file produced by GCC is then parsed by trackgcroot.py.
 #
 
+IS_64_BITS = sys.maxint > 2147483647
 
 class AsmGcRootFrameworkGCTransformer(FrameworkGCTransformer):
     _asmgcc_save_restore_arguments = None
@@ -326,7 +327,7 @@
             ll_assert(reg < CALLEE_SAVED_REGS, "bad register location")
             return callee.regs_stored_at[reg]
         elif kind == LOC_ESP_PLUS:    # in the caller stack frame at N(%esp)
-            esp_in_caller = callee.frame_address + 4
+            esp_in_caller = callee.frame_address + sizeofaddr
             return esp_in_caller + offset
         elif kind == LOC_EBP_PLUS:    # in the caller stack frame at N(%ebp)
             ebp_in_caller = callee.regs_stored_at[INDEX_OF_EBP].address[0]
@@ -415,11 +416,12 @@
     key1 = addr1.address[0]
     key2 = addr2.address[0]
     if key1 < key2:
-        return -1
+        result = -1
     elif key1 == key2:
-        return 0
+        result = 0
     else:
-        return 1
+        result = 1
+    return rffi.cast(rffi.INT, result)
 
 # ____________________________________________________________
 
@@ -464,9 +466,15 @@
 #   - frame address (actually the addr of the retaddr of the current function;
 #                    that's the last word of the frame in memory)
 #
-CALLEE_SAVED_REGS = 4       # there are 4 callee-saved registers
-INDEX_OF_EBP      = 3
-FRAME_PTR         = CALLEE_SAVED_REGS    # the frame is at index 4 in the array
+
+if IS_64_BITS:
+    CALLEE_SAVED_REGS = 6
+    INDEX_OF_EBP      = 5
+    FRAME_PTR         = CALLEE_SAVED_REGS
+else:
+    CALLEE_SAVED_REGS = 4       # there are 4 callee-saved registers
+    INDEX_OF_EBP      = 3
+    FRAME_PTR         = CALLEE_SAVED_REGS    # the frame is at index 4 in the array
 
 ASM_CALLBACK_PTR = lltype.Ptr(lltype.FuncType([], lltype.Void))
 

Modified: pypy/branch/jit-bounds/pypy/rpython/memory/gctypelayout.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/rpython/memory/gctypelayout.py	(original)
+++ pypy/branch/jit-bounds/pypy/rpython/memory/gctypelayout.py	Thu Sep  9 18:10:18 2010
@@ -3,6 +3,7 @@
 from pypy.rpython.lltypesystem.lloperation import llop
 from pypy.rlib.objectmodel import we_are_translated
 from pypy.rlib.debug import ll_assert
+from pypy.rlib.rarithmetic import intmask
 from pypy.tool.identity_dict import identity_dict
 
 
@@ -122,8 +123,8 @@
 T_HAS_GCPTR_IN_VARSIZE = 0x20000
 T_IS_GCARRAY_OF_GCPTR  = 0x40000
 T_IS_WEAKREF           = 0x80000
-T_KEY_MASK          = 0xFF000000
-T_KEY_VALUE         = 0x7A000000    # bug detection only
+T_KEY_MASK             = intmask(0xFF000000)
+T_KEY_VALUE            = intmask(0x7A000000)    # bug detection only
 
 def _check_valid_type_info(p):
     ll_assert(p.infobits & T_KEY_MASK == T_KEY_VALUE, "invalid type_id")

Modified: pypy/branch/jit-bounds/pypy/rpython/module/ll_os.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/rpython/module/ll_os.py	(original)
+++ pypy/branch/jit-bounds/pypy/rpython/module/ll_os.py	Thu Sep  9 18:10:18 2010
@@ -1046,7 +1046,7 @@
                                                         rffi.VOIDP,
                                                         rwin32.DWORD],
                                          rwin32.BOOL)
-            _open_osfhandle = self.llexternal('_open_osfhandle', [rffi.ULONG,
+            _open_osfhandle = self.llexternal('_open_osfhandle', [rffi.INTPTR_T,
                                                                   rffi.INT],
                                               rffi.INT)
             null = lltype.nullptr(rffi.VOIDP.TO)
@@ -1059,8 +1059,8 @@
                     error = 0
                 else:
                     error = rwin32.GetLastError()
-                hread = pread[0]
-                hwrite = pwrite[0]
+                hread = rffi.cast(rffi.INTPTR_T, pread[0])
+                hwrite = rffi.cast(rffi.INTPTR_T, pwrite[0])
                 lltype.free(pwrite, flavor='raw')
                 lltype.free(pread, flavor='raw')
                 if error:

Modified: pypy/branch/jit-bounds/pypy/rpython/module/ll_os_stat.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/rpython/module/ll_os_stat.py	(original)
+++ pypy/branch/jit-bounds/pypy/rpython/module/ll_os_stat.py	Thu Sep  9 18:10:18 2010
@@ -437,5 +437,5 @@
 def time_t_to_FILE_TIME(time, filetime):
     ft = lltype.r_longlong((time + secs_between_epochs) * 10000000)
     filetime.c_dwHighDateTime = lltype.r_uint(ft >> 32)
-    filetime.c_dwLowDateTime = lltype.r_uint(ft & ((1 << 32) - 1))
+    filetime.c_dwLowDateTime = lltype.r_uint(ft & lltype.r_uint(-1))
 

Modified: pypy/branch/jit-bounds/pypy/rpython/module/ll_win32file.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/rpython/module/ll_win32file.py	(original)
+++ pypy/branch/jit-bounds/pypy/rpython/module/ll_win32file.py	Thu Sep  9 18:10:18 2010
@@ -265,7 +265,8 @@
         hFile = CreateFile(path,
                            FILE_WRITE_ATTRIBUTES, 0,
                            None, OPEN_EXISTING,
-                           FILE_FLAG_BACKUP_SEMANTICS, 0)
+                           FILE_FLAG_BACKUP_SEMANTICS,
+                           rwin32.NULL_HANDLE)
         if hFile == rwin32.INVALID_HANDLE_VALUE:
             raise rwin32.lastWindowsError()
         ctime = lltype.nullptr(rwin32.FILETIME)

Modified: pypy/branch/jit-bounds/pypy/rpython/test/test_rint.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/rpython/test/test_rint.py	(original)
+++ pypy/branch/jit-bounds/pypy/rpython/test/test_rint.py	Thu Sep  9 18:10:18 2010
@@ -117,10 +117,10 @@
         assert self.ll_to_string(res) == '413974738222117'
 
     def test_unsigned(self):
-        bigvalue = sys.maxint + 17
+        bigvalue = r_uint(sys.maxint + 17)
         def dummy(i):
             i = r_uint(i)
-            j = r_uint(bigvalue)
+            j = bigvalue
             return i < j
 
         res = self.interpret(dummy,[0])

Modified: pypy/branch/jit-bounds/pypy/rpython/tool/rffi_platform.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/rpython/tool/rffi_platform.py	(original)
+++ pypy/branch/jit-bounds/pypy/rpython/tool/rffi_platform.py	Thu Sep  9 18:10:18 2010
@@ -8,6 +8,7 @@
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
 from pypy.translator.platform import CompilationError
 from pypy.tool.udir import udir
+from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong, intmask
 
 # ____________________________________________________________
 #
@@ -371,7 +372,7 @@
         yield '}'
 
     def build_result(self, info, config_result):
-        return info['value']
+        return expose_value_as_rpython(info['value'])
 
 class DefinedConstantInteger(CConfigEntry):
     """An entry in a CConfig class that stands for an externally
@@ -397,7 +398,7 @@
 
     def build_result(self, info, config_result):
         if info["defined"]:
-            return info['value']
+            return expose_value_as_rpython(info['value'])
         return None
 
 class DefinedConstantString(CConfigEntry):
@@ -620,6 +621,20 @@
     raise TypeError("conflicting field type %r for %r" % (fieldtype,
                                                           fieldname))
 
+def expose_value_as_rpython(value):
+    if intmask(value) == value:
+        return value
+    if r_uint(value) == value:
+        return r_uint(value)
+    try:
+        if r_longlong(value) == value:
+            return r_longlong(value)
+    except OverflowError:
+        pass
+    if r_ulonglong(value) == value:
+        return r_ulonglong(value)
+    raise OverflowError("value %d does not fit into any RPython integer type"
+                        % (value,))
 
 C_HEADER = """
 #include <stdio.h>

Modified: pypy/branch/jit-bounds/pypy/rpython/tool/test/test_rffi_platform.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/rpython/tool/test/test_rffi_platform.py	(original)
+++ pypy/branch/jit-bounds/pypy/rpython/tool/test/test_rffi_platform.py	Thu Sep  9 18:10:18 2010
@@ -5,6 +5,7 @@
 from pypy.tool.udir import udir
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
 from pypy.translator.platform import platform
+from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong
 
 def import_ctypes():
     try:
@@ -357,3 +358,19 @@
     padding = list(S._hints['padding'])
     d = {'c_c1': 'char'}
     assert S._hints['get_padding_drop'](d) == padding
+
+def test_expose_value_as_rpython():
+    def get(x):
+        x = rffi_platform.expose_value_as_rpython(x)
+        return (x, type(x))
+    assert get(5) == (5, int)
+    assert get(-82) == (-82, int)
+    assert get(sys.maxint) == (sys.maxint, int)
+    assert get(sys.maxint+1) == (sys.maxint+1, r_uint)
+    if sys.maxint == 2147483647:
+        assert get(9999999999) == (9999999999, r_longlong)
+        assert get(-9999999999) == (-9999999999, r_longlong)
+        assert get(2**63) == (2**63, r_ulonglong)
+        assert get(-2**63) == (-2**63, r_longlong)
+    py.test.raises(OverflowError, get, -2**63-1)
+    py.test.raises(OverflowError, get, 2**64)

Modified: pypy/branch/jit-bounds/pypy/translator/c/database.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/translator/c/database.py	(original)
+++ pypy/branch/jit-bounds/pypy/translator/c/database.py	Thu Sep  9 18:10:18 2010
@@ -2,7 +2,7 @@
      Primitive, Ptr, typeOf, RuntimeTypeInfo, \
      Struct, Array, FuncType, PyObject, Void, \
      ContainerType, OpaqueType, FixedSizeArray, _uninitialized
-from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.lltypesystem import lltype, rffi
 from pypy.rpython.lltypesystem.llmemory import WeakRef, _WeakRefType, GCREF
 from pypy.rpython.lltypesystem.rffi import CConstant
 from pypy.rpython.lltypesystem import llgroup
@@ -183,6 +183,12 @@
         if isinstance(T, Primitive) or T == GCREF:
             return PrimitiveName[T](obj, self)
         elif isinstance(T, Ptr):
+            if (isinstance(T.TO, OpaqueType) and
+                T.TO.hints.get('c_pointer_typedef') is not None):
+                if obj._obj is not None:
+                    value = rffi.cast(rffi.SSIZE_T, obj)
+                    return '((%s) %s)' % (cdecl(self.gettype(T), ''),
+                                          self.get(value))
             if obj:   # test if the ptr is non-NULL
                 try:
                     container = obj._obj

Modified: pypy/branch/jit-bounds/pypy/translator/c/gcc/instruction.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/translator/c/gcc/instruction.py	(original)
+++ pypy/branch/jit-bounds/pypy/translator/c/gcc/instruction.py	Thu Sep  9 18:10:18 2010
@@ -5,6 +5,14 @@
 LOC_MASK      = 0x03
 LOC_NOWHERE   = LOC_REG | 0
 
+# x86-32 registers sometimes used to pass arguments when gcc optimizes
+# a function's calling convention
+ARGUMENT_REGISTERS_32 = ('%eax', '%edx', '%ecx')
+
+# x86-64 registers used to pass arguments
+ARGUMENT_REGISTERS_64 = ('%rdi', '%rsi', '%rdx', '%rcx', '%r8', '%r9')
+
+
 def frameloc_esp(offset):
     assert offset >= 0
     assert offset % 4 == 0
@@ -19,7 +27,8 @@
 
 
 class SomeNewValue(object):
-    pass
+    def __repr__(self):
+        return 'somenewvalue'
 somenewvalue = SomeNewValue()
 
 class LocalVar(object):
@@ -42,7 +51,7 @@
         else:
             return 1
 
-    def getlocation(self, framesize, uses_frame_pointer):
+    def getlocation(self, framesize, uses_frame_pointer, wordsize):
         if (self.hint == 'esp' or not uses_frame_pointer
             or self.ofs_from_frame_end % 2 != 0):
             # try to use esp-relative addressing
@@ -52,7 +61,7 @@
             # we can get an odd value if the framesize is marked as bogus
             # by visit_andl()
         assert uses_frame_pointer
-        ofs_from_ebp = self.ofs_from_frame_end + 4
+        ofs_from_ebp = self.ofs_from_frame_end + wordsize
         return frameloc_ebp(ofs_from_ebp)
 
 
@@ -81,22 +90,28 @@
         self.previous_insns = []   # all insns that jump (or fallthrough) here
 
 class InsnFunctionStart(Insn):
+    _args_ = ['arguments']
     framesize = 0
     previous_insns = ()
-    def __init__(self, registers):
+    def __init__(self, registers, wordsize):
         self.arguments = {}
         for reg in registers:
             self.arguments[reg] = somenewvalue
+        self.wordsize = wordsize
 
     def source_of(self, localvar, tag):
         if localvar not in self.arguments:
-            if localvar in ('%eax', '%edx', '%ecx'):
+            if self.wordsize == 4 and localvar in ARGUMENT_REGISTERS_32:
                 # xxx this might show a bug in trackgcroot.py failing to
                 # figure out which instruction stored a value in these
                 # registers.  However, this case also occurs when the
                 # the function's calling convention was optimized by gcc:
                 # the 3 registers above are then used to pass arguments
                 pass
+            elif self.wordsize == 8 and localvar in ARGUMENT_REGISTERS_64:
+                # this is normal: these registers are always used to
+                # pass arguments
+                pass
             else:
                 assert (isinstance(localvar, LocalVar) and
                         localvar.ofs_from_frame_end > 0), (
@@ -218,15 +233,16 @@
         return {self.loc: None}
 
 class InsnPrologue(Insn):
+    def __init__(self, wordsize):
+        self.wordsize = wordsize
     def __setattr__(self, attr, value):
         if attr == 'framesize':
-            assert value == 4, ("unrecognized function prologue - "
-                                "only supports push %ebp; movl %esp, %ebp")
+            assert value == self.wordsize, (
+                "unrecognized function prologue - "
+                "only supports push %ebp; movl %esp, %ebp")
         Insn.__setattr__(self, attr, value)
 
 class InsnEpilogue(Insn):
     def __init__(self, framesize=None):
         if framesize is not None:
             self.framesize = framesize
-
-

Modified: pypy/branch/jit-bounds/pypy/translator/c/gcc/test/conftest.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/translator/c/gcc/test/conftest.py	(original)
+++ pypy/branch/jit-bounds/pypy/translator/c/gcc/test/conftest.py	Thu Sep  9 18:10:18 2010
@@ -1,8 +1,6 @@
 import py
 from pypy.jit.backend import detect_cpu
-
 cpu = detect_cpu.autodetect()
 def pytest_runtest_setup(item):
-    if cpu != 'x86':
+    if cpu not in ('x86', 'x86_64'):
         py.test.skip("x86 directory skipped: cpu is %r" % (cpu,))
-    

Modified: pypy/branch/jit-bounds/pypy/translator/c/gcc/test/test_trackgcroot.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/translator/c/gcc/test/test_trackgcroot.py	(original)
+++ pypy/branch/jit-bounds/pypy/translator/c/gcc/test/test_trackgcroot.py	Thu Sep  9 18:10:18 2010
@@ -1,51 +1,52 @@
 import py
 import sys, re
-from pypy.translator.c.gcc.trackgcroot import format_location
-from pypy.translator.c.gcc.trackgcroot import format_callshape
 from pypy.translator.c.gcc.trackgcroot import LOC_NOWHERE, LOC_REG
 from pypy.translator.c.gcc.trackgcroot import LOC_EBP_PLUS, LOC_EBP_MINUS
 from pypy.translator.c.gcc.trackgcroot import LOC_ESP_PLUS
 from pypy.translator.c.gcc.trackgcroot import ElfAssemblerParser
 from pypy.translator.c.gcc.trackgcroot import DarwinAssemblerParser
-from pypy.translator.c.gcc.trackgcroot import compress_callshape
-from pypy.translator.c.gcc.trackgcroot import decompress_callshape
 from pypy.translator.c.gcc.trackgcroot import PARSERS
+from pypy.translator.c.gcc.trackgcroot import ElfFunctionGcRootTracker32
 from StringIO import StringIO
+import py.test
 
 this_dir = py.path.local(__file__).dirpath()
 
 
 def test_format_location():
-    assert format_location(LOC_NOWHERE) == '?'
-    assert format_location(LOC_REG | (1<<2)) == '%ebx'
-    assert format_location(LOC_REG | (2<<2)) == '%esi'
-    assert format_location(LOC_REG | (3<<2)) == '%edi'
-    assert format_location(LOC_REG | (4<<2)) == '%ebp'
-    assert format_location(LOC_EBP_PLUS + 0) == '(%ebp)'
-    assert format_location(LOC_EBP_PLUS + 4) == '4(%ebp)'
-    assert format_location(LOC_EBP_MINUS + 4) == '-4(%ebp)'
-    assert format_location(LOC_ESP_PLUS + 0) == '(%esp)'
-    assert format_location(LOC_ESP_PLUS + 4) == '4(%esp)'
+    cls = ElfFunctionGcRootTracker32
+    assert cls.format_location(LOC_NOWHERE) == '?'
+    assert cls.format_location(LOC_REG | (1<<2)) == '%ebx'
+    assert cls.format_location(LOC_REG | (2<<2)) == '%esi'
+    assert cls.format_location(LOC_REG | (3<<2)) == '%edi'
+    assert cls.format_location(LOC_REG | (4<<2)) == '%ebp'
+    assert cls.format_location(LOC_EBP_PLUS + 0) == '(%ebp)'
+    assert cls.format_location(LOC_EBP_PLUS + 4) == '4(%ebp)'
+    assert cls.format_location(LOC_EBP_MINUS + 4) == '-4(%ebp)'
+    assert cls.format_location(LOC_ESP_PLUS + 0) == '(%esp)'
+    assert cls.format_location(LOC_ESP_PLUS + 4) == '4(%esp)'
 
 def test_format_callshape():
+    cls = ElfFunctionGcRootTracker32
     expected = ('{4(%ebp) '               # position of the return address
                 '| 8(%ebp), 12(%ebp), 16(%ebp), 20(%ebp) '  # 4 saved regs
                 '| 24(%ebp), 28(%ebp)}')                    # GC roots
-    assert format_callshape((LOC_EBP_PLUS+4,
-                             LOC_EBP_PLUS+8,
-                             LOC_EBP_PLUS+12,
-                             LOC_EBP_PLUS+16,
-                             LOC_EBP_PLUS+20,
-                             LOC_EBP_PLUS+24,
-                             LOC_EBP_PLUS+28)) == expected
+    assert cls.format_callshape((LOC_EBP_PLUS+4,
+                                 LOC_EBP_PLUS+8,
+                                 LOC_EBP_PLUS+12,
+                                 LOC_EBP_PLUS+16,
+                                 LOC_EBP_PLUS+20,
+                                 LOC_EBP_PLUS+24,
+                                 LOC_EBP_PLUS+28)) == expected
 
 def test_compress_callshape():
+    cls = ElfFunctionGcRootTracker32
     shape = (1, 127, 0x1234, 0x5678, 0x234567,
              0x765432, 0x61626364, 0x41424344)
-    bytes = list(compress_callshape(shape))
+    bytes = list(cls.compress_callshape(shape))
     print bytes
     assert len(bytes) == 1+1+2+3+4+4+5+5+1
-    assert decompress_callshape(bytes) == list(shape)
+    assert cls.decompress_callshape(bytes) == list(shape)
 
 def test_find_functions_elf():
     source = """\
@@ -108,7 +109,7 @@
  
 def test_computegcmaptable():
     tests = []
-    for format in ('elf', 'darwin', 'msvc'):
+    for format in ('elf', 'darwin', 'msvc', 'elf64'):
         for path in this_dir.join(format).listdir("track*.s"):
             n = path.purebasename[5:]
             try:
@@ -138,7 +139,7 @@
     tabledict = {}
     seen = {}
     for entry in table:
-        print '%s: %s' % (entry[0], format_callshape(entry[1]))
+        print '%s: %s' % (entry[0], tracker.format_callshape(entry[1]))
         tabledict[entry[0]] = entry[1]
     # find the ";; expected" lines
     prevline = ""
@@ -151,7 +152,7 @@
             label = prevmatch.group(1)
             assert label in tabledict
             got = tabledict[label]
-            assert format_callshape(got) == expected
+            assert tracker.format_callshape(got) == expected
             seen[label] = True
             if format == 'msvc':
                 expectedlines.insert(i-2, 'PUBLIC\t%s\n' % (label,))

Modified: pypy/branch/jit-bounds/pypy/translator/c/gcc/trackgcroot.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/translator/c/gcc/trackgcroot.py	(original)
+++ pypy/branch/jit-bounds/pypy/translator/c/gcc/trackgcroot.py	Thu Sep  9 18:10:18 2010
@@ -72,7 +72,7 @@
             if self.is_stack_bottom:
                 retaddr = LOC_NOWHERE     # end marker for asmgcroot.py
             elif self.uses_frame_pointer:
-                retaddr = frameloc_ebp(4)
+                retaddr = frameloc_ebp(self.WORD)
             else:
                 retaddr = frameloc_esp(insn.framesize)
             shape = [retaddr]
@@ -84,7 +84,8 @@
             for localvar, tag in insn.gcroots.items():
                 if isinstance(localvar, LocalVar):
                     loc = localvar.getlocation(insn.framesize,
-                                               self.uses_frame_pointer)
+                                               self.uses_frame_pointer,
+                                               self.WORD)
                 elif localvar in self.REG2LOC:
                     loc = self.REG2LOC[localvar]
                 else:
@@ -148,7 +149,7 @@
             lst.append(previnsn)
 
     def parse_instructions(self):
-        self.insns = [InsnFunctionStart(self.CALLEE_SAVE_REGISTERS)]
+        self.insns = [InsnFunctionStart(self.CALLEE_SAVE_REGISTERS, self.WORD)]
         ignore_insns = False
         for lineno, line in enumerate(self.lines):
             if lineno < self.skip:
@@ -263,7 +264,7 @@
                     ofs_from_ebp = int(match.group(1) or '0')
                     if self.format == 'msvc':
                         ofs_from_ebp += int(match.group(2) or '0')
-                    localvar = ofs_from_ebp - 4
+                    localvar = ofs_from_ebp - self.WORD
                     assert localvar != 0    # that's the return address
                     return LocalVar(localvar, hint='ebp')
             return localvar
@@ -357,6 +358,56 @@
                 self.lines.insert(call.lineno+1, '\t.globl\t%s\n' % (label,))
         call.global_label = label
 
+    @classmethod
+    def compress_callshape(cls, shape):
+        # For a single shape, this turns the list of integers into a list of
+        # bytes and reverses the order of the entries.  The length is
+        # encoded by inserting a 0 marker after the gc roots coming from
+        # shape[N:] and before the N values coming from shape[N-1] to
+        # shape[0] (for N == 5 on 32-bit or 7 on 64-bit platforms).
+        # In practice it seems that shapes contain many integers
+        # whose value is up to a few thousands, which the algorithm below
+        # compresses down to 2 bytes.  Very small values compress down to a
+        # single byte.
+
+        # Callee-save regs plus ret addr
+        min_size = len(cls.CALLEE_SAVE_REGISTERS) + 1
+
+        assert len(shape) >= min_size
+        shape = list(shape)
+        assert 0 not in shape[min_size:]
+        shape.insert(min_size, 0)
+        result = []
+        for loc in shape:
+            assert loc >= 0
+            flag = 0
+            while loc >= 0x80:
+                result.append(int(loc & 0x7F) | flag)
+                flag = 0x80
+                loc >>= 7
+            result.append(int(loc) | flag)
+        result.reverse()
+        return result
+
+    @classmethod
+    def decompress_callshape(cls, bytes):
+        # For tests.  This logic is copied in asmgcroot.py.
+        result = []
+        n = 0
+        while n < len(bytes):
+            value = 0
+            while True:
+                b = bytes[n]
+                n += 1
+                value += b
+                if b < 0x80:
+                    break
+                value = (value - 0x80) << 7
+            result.append(value)
+        result.reverse()
+        assert result[5] == 0
+        del result[5]
+        return result
     # ____________________________________________________________
 
     CANNOT_COLLECT = {    # some of the most used functions that cannot collect
@@ -385,10 +436,9 @@
         'inc', 'dec', 'not', 'neg', 'or', 'and', 'sbb', 'adc',
         'shl', 'shr', 'sal', 'sar', 'rol', 'ror', 'mul', 'imul', 'div', 'idiv',
         'bswap', 'bt', 'rdtsc',
+        'punpck', 'pshufd', 
         # zero-extending moves should not produce GC pointers
         'movz',
-        # quadword operations
-        'movq',
         ])
 
     visit_movb = visit_nop
@@ -400,7 +450,7 @@
     visit_xorb = visit_nop
     visit_xorw = visit_nop
 
-    def visit_addl(self, line, sign=+1):
+    def _visit_add(self, line, sign=+1):
         match = self.r_binaryinsn.match(line)
         source = match.group("source")
         target = match.group("target")
@@ -415,8 +465,8 @@
         else:
             return []
 
-    def visit_subl(self, line):
-        return self.visit_addl(line, sign=-1)
+    def _visit_sub(self, line):
+        return self._visit_add(line, sign=-1)
 
     def unary_insn(self, line):
         match = self.r_unaryinsn.match(line)
@@ -439,8 +489,6 @@
         else:
             return []
 
-    visit_xorl = binary_insn   # used in "xor reg, reg" to create a NULL GC ptr
-    visit_orl = binary_insn
     # The various cmov* operations
     for name in '''
         e ne g ge l le a ae b be p np s ns o no
@@ -448,7 +496,7 @@
         locals()['visit_cmov' + name] = binary_insn
         locals()['visit_cmov' + name + 'l'] = binary_insn
 
-    def visit_andl(self, line):
+    def _visit_and(self, line):
         match = self.r_binaryinsn.match(line)
         target = match.group("target")
         if target == self.ESP:
@@ -460,9 +508,7 @@
         else:
             return self.binary_insn(line)
 
-    visit_and = visit_andl
-
-    def visit_leal(self, line):
+    def _visit_lea(self, line):
         match = self.r_binaryinsn.match(line)
         target = match.group("target")
         if target == self.ESP:
@@ -474,7 +520,7 @@
                     raise UnrecognizedOperation('epilogue without prologue')
                 ofs_from_ebp = int(match.group(1) or '0')
                 assert ofs_from_ebp <= 0
-                framesize = 4 - ofs_from_ebp
+                framesize = self.WORD - ofs_from_ebp
             else:
                 match = self.r_localvar_esp.match(source)
                 # leal 12(%esp), %esp
@@ -489,17 +535,23 @@
     def insns_for_copy(self, source, target):
         source = self.replace_symbols(source)
         target = self.replace_symbols(target)
-        if source == self.ESP or target == self.ESP:
+        if target == self.ESP:
             raise UnrecognizedOperation('%s -> %s' % (source, target))
         elif self.r_localvar.match(target):
             if self.r_localvar.match(source):
+                # eg, movl %eax, %ecx: possibly copies a GC root
                 return [InsnCopyLocal(source, target)]
             else:
+                # eg, movl (%eax), %edi or mov %esp, %edi: load a register
+                # from "outside".  If it contains a pointer to a GC root,
+                # it will be announced later with the GCROOT macro.
                 return [InsnSetLocal(target, [source])]
         else:
+            # eg, movl %ebx, (%edx) or mov %ebp, %esp: does not write into
+            # a general register
             return []
 
-    def visit_movl(self, line):
+    def _visit_mov(self, line):
         match = self.r_binaryinsn.match(line)
         source = match.group("source")
         target = match.group("target")
@@ -513,34 +565,24 @@
                           # gcc -fno-unit-at-a-time.
         return self.insns_for_copy(source, target)
 
-    visit_mov = visit_movl
-
-    def visit_pushl(self, line):
+    def _visit_push(self, line):
         match = self.r_unaryinsn.match(line)
         source = match.group(1)
-        return [InsnStackAdjust(-4)] + self.insns_for_copy(source, self.TOP_OF_STACK)
-
-    def visit_pushw(self, line):
-        return [InsnStackAdjust(-2)]   # rare but not impossible
+        return [InsnStackAdjust(-self.WORD)] + self.insns_for_copy(source, self.TOP_OF_STACK)
 
     def _visit_pop(self, target):
-        return self.insns_for_copy(self.TOP_OF_STACK, target) + [InsnStackAdjust(+4)]
-
-    def visit_popl(self, line):
-        match = self.r_unaryinsn.match(line)
-        target = match.group(1)
-        return self._visit_pop(target)
+        return self.insns_for_copy(self.TOP_OF_STACK, target) + [InsnStackAdjust(+self.WORD)]
 
     def _visit_prologue(self):
         # for the prologue of functions that use %ebp as frame pointer
         self.uses_frame_pointer = True
         self.r_localvar = self.r_localvarfp
-        return [InsnPrologue()]
+        return [InsnPrologue(self.WORD)]
 
     def _visit_epilogue(self):
         if not self.uses_frame_pointer:
             raise UnrecognizedOperation('epilogue without prologue')
-        return [InsnEpilogue(4)]
+        return [InsnEpilogue(self.WORD)]
 
     def visit_leave(self, line):
         return self._visit_epilogue() + self._visit_pop(self.EBP)
@@ -662,7 +704,7 @@
     visit_jc = conditional_jump
     visit_jnc = conditional_jump
 
-    def visit_xchgl(self, line):
+    def _visit_xchg(self, line):
         # only support the format used in VALGRIND_DISCARD_TRANSLATIONS
         # which is to use a marker no-op "xchgl %ebx, %ebx"
         match = self.r_binaryinsn.match(line)
@@ -741,8 +783,172 @@
                 insns.append(InsnStackAdjust(16))
         return insns
 
+    # __________ debugging output __________
+
+    @classmethod
+    def format_location(cls, loc):
+        # A 'location' is a single number describing where a value is stored
+        # across a call.  It can be in one of the CALLEE_SAVE_REGISTERS, or
+        # in the stack frame at an address relative to either %esp or %ebp.
+        # The last two bits of the location number are used to tell the cases
+        # apart; see format_location().
+        assert loc >= 0
+        kind = loc & LOC_MASK
+        if kind == LOC_REG:
+            if loc == LOC_NOWHERE:
+                return '?'
+            reg = (loc >> 2) - 1
+            return '%' + cls.CALLEE_SAVE_REGISTERS[reg].replace("%", "")
+        else:
+            offset = loc & ~ LOC_MASK
+            if kind == LOC_EBP_PLUS:
+                result = '(%' + cls.EBP.replace("%", "") + ')'
+            elif kind == LOC_EBP_MINUS:
+                result = '(%' + cls.EBP.replace("%", "") + ')'
+                offset = -offset
+            elif kind == LOC_ESP_PLUS:
+                result = '(%' + cls.ESP.replace("%", "") + ')'
+            else:
+                assert 0, kind
+            if offset != 0:
+                result = str(offset) + result
+            return result
+
+    @classmethod
+    def format_callshape(cls, shape):
+        # A 'call shape' is a tuple of locations in the sense of
+        # format_location().  They describe where in a function frame
+        # interesting values are stored, when this function executes a 'call'
+        # instruction.
+        #
+        #   shape[0]    is the location that stores the fn's own return
+        #               address (not the return address for the currently
+        #               executing 'call')
+        #
+        #   shape[1..N] is where the fn saved its own caller's value of a
+        #               certain callee save register. (where N is the number
+        #               of callee save registers.)
+        #
+        #   shape[>N]   are GC roots: where the fn has put its local GCPTR
+        #               vars
+        #
+        num_callee_save_regs = len(cls.CALLEE_SAVE_REGISTERS)
+        assert isinstance(shape, tuple)
+        # + 1 for the return address
+        assert len(shape) >= (num_callee_save_regs + 1)
+        result = [cls.format_location(loc) for loc in shape]
+        return '{%s | %s | %s}' % (result[0],
+                                   ', '.join(result[1:(num_callee_save_regs+1)]),
+                                   ', '.join(result[(num_callee_save_regs+1):]))
+
+
+class FunctionGcRootTracker32(FunctionGcRootTracker):
+    WORD = 4
+
+    visit_mov = FunctionGcRootTracker._visit_mov
+    visit_movl = FunctionGcRootTracker._visit_mov
+    visit_pushl = FunctionGcRootTracker._visit_push
+    visit_leal = FunctionGcRootTracker._visit_lea
+
+    visit_addl = FunctionGcRootTracker._visit_add
+    visit_subl = FunctionGcRootTracker._visit_sub
+    visit_andl = FunctionGcRootTracker._visit_and
+    visit_and = FunctionGcRootTracker._visit_and
+
+    visit_xchgl = FunctionGcRootTracker._visit_xchg
+
+    # used in "xor reg, reg" to create a NULL GC ptr
+    visit_xorl = FunctionGcRootTracker.binary_insn
+    visit_orl = FunctionGcRootTracker.binary_insn     # unsure about this one
+
+    # occasionally used on 32-bits to move floats around
+    visit_movq = FunctionGcRootTracker.visit_nop
+
+    def visit_pushw(self, line):
+        return [InsnStackAdjust(-2)]   # rare but not impossible
 
-class ElfFunctionGcRootTracker(FunctionGcRootTracker):
+    def visit_popl(self, line):
+        match = self.r_unaryinsn.match(line)
+        target = match.group(1)
+        return self._visit_pop(target)
+
+class FunctionGcRootTracker64(FunctionGcRootTracker):
+    WORD = 8
+
+    # Regex ignores destination
+    r_save_xmm_register = re.compile(r"\tmovaps\s+%xmm(\d+)")
+
+    def _maybe_32bit_dest(func):
+        def wrapper(self, line):
+            # Using a 32-bit reg as a destination in 64-bit mode zero-extends
+            # to 64-bits, so sometimes gcc uses a 32-bit operation to copy a
+            # statically known pointer to a register
+
+            # %eax -> %rax
+            new_line = re.sub(r"%e(ax|bx|cx|dx|di|si)$", r"%r\1", line)
+            # %r10d -> %r10
+            new_line = re.sub(r"%r(\d+)d$", r"%r\1", new_line)
+            return func(self, new_line)
+        return wrapper
+
+    visit_addl = FunctionGcRootTracker.visit_nop
+    visit_subl = FunctionGcRootTracker.visit_nop
+    visit_leal = FunctionGcRootTracker.visit_nop
+
+    visit_cltq = FunctionGcRootTracker.visit_nop
+
+    visit_movq = FunctionGcRootTracker._visit_mov
+    # just a special assembler mnemonic for mov
+    visit_movabsq = FunctionGcRootTracker._visit_mov
+    visit_mov = _maybe_32bit_dest(FunctionGcRootTracker._visit_mov)
+    visit_movl = visit_mov
+
+    visit_xorl = _maybe_32bit_dest(FunctionGcRootTracker.binary_insn)
+    
+    visit_pushq = FunctionGcRootTracker._visit_push
+
+    visit_addq = FunctionGcRootTracker._visit_add
+    visit_subq = FunctionGcRootTracker._visit_sub
+
+    visit_leaq = FunctionGcRootTracker._visit_lea
+
+    visit_xorq = FunctionGcRootTracker.binary_insn
+
+    # FIXME: similar to visit_popl for 32-bit
+    def visit_popq(self, line):
+        match = self.r_unaryinsn.match(line)
+        target = match.group(1)
+        return self._visit_pop(target)
+
+    def visit_jmp(self, line):
+        # On 64-bit, %al is used when calling varargs functions to specify an
+        # upper-bound on the number of xmm registers used in the call. gcc
+        # uses %al to compute an indirect jump that looks like:
+        #
+        #     jmp *[some register]
+        #     movaps %xmm7, [stack location]
+        #     movaps %xmm6, [stack location]
+        #     movaps %xmm5, [stack location]
+        #     movaps %xmm4, [stack location]
+        #     movaps %xmm3, [stack location]
+        #     movaps %xmm2, [stack location]
+        #     movaps %xmm1, [stack location]
+        #     movaps %xmm0, [stack location]
+        #
+        # The jmp is always to somewhere in the block of "movaps"
+        # instructions, according to how many xmm registers need to be saved
+        # to the stack. The point of all this is that we can safely ignore
+        # jmp instructions of that form.
+        if (self.currentlineno + 8) < len(self.lines) and self.r_unaryinsn_star.match(line):
+            matches = [self.r_save_xmm_register.match(self.lines[self.currentlineno + 1 + i]) for i in range(8)]
+            if all(m and int(m.group(1)) == (7 - i) for i, m in enumerate(matches)):
+                return []
+
+        return FunctionGcRootTracker.visit_jmp(self, line)
+
+
+
+class ElfFunctionGcRootTracker32(FunctionGcRootTracker32):
     format = 'elf'
 
     ESP     = '%esp'
@@ -791,7 +997,65 @@
         match = self.r_functionend.match(lines[-1])
         assert funcname == match.group(1)
         assert funcname == match.group(2)
-        super(ElfFunctionGcRootTracker, self).__init__(
+        super(ElfFunctionGcRootTracker32, self).__init__(
+            funcname, lines, filetag)
+
+    def extract_immediate(self, value):
+        if not value.startswith('$'):
+            return None
+        return int(value[1:])
+
+ElfFunctionGcRootTracker32.init_regexp()
+
+class ElfFunctionGcRootTracker64(FunctionGcRootTracker64):
+    format = 'elf64'
+    ESP = '%rsp'
+    EBP = '%rbp'
+    EAX = '%rax'
+    CALLEE_SAVE_REGISTERS = ['%rbx', '%r12', '%r13', '%r14', '%r15', '%rbp']
+    REG2LOC = dict((_reg, LOC_REG | ((_i+1)<<2))
+                   for _i, _reg in enumerate(CALLEE_SAVE_REGISTERS))
+    OPERAND = r'(?:[-\w$%+.:@"]+(?:[(][\w%,]+[)])?|[(][\w%,]+[)])'
+    LABEL   = r'([a-zA-Z_$.][a-zA-Z0-9_$@.]*)'
+    OFFSET_LABELS   = 2**30
+    TOP_OF_STACK = '0(%rsp)'
+
+    r_functionstart = re.compile(r"\t.type\s+"+LABEL+",\s*[@]function\s*$")
+    r_functionend   = re.compile(r"\t.size\s+"+LABEL+",\s*[.]-"+LABEL+"\s*$")
+    LOCALVAR = r"%rax|%rbx|%rcx|%rdx|%rdi|%rsi|%rbp|%r8|%r9|%r10|%r11|%r12|%r13|%r14|%r15|-?\d*[(]%rsp[)]"
+    LOCALVARFP = LOCALVAR + r"|-?\d*[(]%rbp[)]"
+    r_localvarnofp  = re.compile(LOCALVAR)
+    r_localvarfp    = re.compile(LOCALVARFP)
+    r_localvar_esp  = re.compile(r"(-?\d*)[(]%rsp[)]")
+    r_localvar_ebp  = re.compile(r"(-?\d*)[(]%rbp[)]")
+
+    r_rel_label      = re.compile(r"(\d+):\s*$")
+    r_jump_rel_label = re.compile(r"\tj\w+\s+"+"(\d+)f"+"\s*$")
+
+    r_unaryinsn_star= re.compile(r"\t[a-z]\w*\s+[*]("+OPERAND+")\s*$")
+    r_jmptable_item = re.compile(r"\t.quad\t"+LABEL+"(-\"[A-Za-z0-9$]+\")?\s*$")
+    r_jmptable_end  = re.compile(r"\t.text|\t.section\s+.text|\t\.align|"+LABEL)
+
+    r_gcroot_marker = re.compile(r"\t/[*] GCROOT ("+LOCALVARFP+") [*]/")
+    r_gcnocollect_marker = re.compile(r"\t/[*] GC_NOCOLLECT ("+OPERAND+") [*]/")
+    r_bottom_marker = re.compile(r"\t/[*] GC_STACK_BOTTOM [*]/")
+
+    FUNCTIONS_NOT_RETURNING = {
+        'abort': None,
+        '_exit': None,
+        '__assert_fail': None,
+        '___assert_rtn': None,
+        'L___assert_rtn$stub': None,
+        'L___eprintf$stub': None,
+        }
+
+    def __init__(self, lines, filetag=0):
+        match = self.r_functionstart.match(lines[0])
+        funcname = match.group(1)
+        match = self.r_functionend.match(lines[-1])
+        assert funcname == match.group(1)
+        assert funcname == match.group(2)
+        super(ElfFunctionGcRootTracker64, self).__init__(
             funcname, lines, filetag)
 
     def extract_immediate(self, value):
@@ -799,9 +1063,9 @@
             return None
         return int(value[1:])
 
-ElfFunctionGcRootTracker.init_regexp()
+ElfFunctionGcRootTracker64.init_regexp()
 
-class DarwinFunctionGcRootTracker(ElfFunctionGcRootTracker):
+class DarwinFunctionGcRootTracker(ElfFunctionGcRootTracker32):
     format = 'darwin'
 
     r_functionstart = re.compile(r"_(\w+):\s*$")
@@ -810,7 +1074,7 @@
     def __init__(self, lines, filetag=0):
         match = self.r_functionstart.match(lines[0])
         funcname = '_' + match.group(1)
-        FunctionGcRootTracker.__init__(self, funcname, lines, filetag)
+        FunctionGcRootTracker32.__init__(self, funcname, lines, filetag)
 
 class Mingw32FunctionGcRootTracker(DarwinFunctionGcRootTracker):
     format = 'mingw32'
@@ -821,7 +1085,7 @@
         '__assert': None,
         }
 
-class MsvcFunctionGcRootTracker(FunctionGcRootTracker):
+class MsvcFunctionGcRootTracker(FunctionGcRootTracker32):
     format = 'msvc'
     ESP = 'esp'
     EBP = 'ebp'
@@ -906,12 +1170,12 @@
         push pop mov lea
         xor sub add
         '''.split():
-        locals()['visit_' + name] = getattr(FunctionGcRootTracker,
+        locals()['visit_' + name] = getattr(FunctionGcRootTracker32,
                                             'visit_' + name + 'l')
 
-    visit_int = FunctionGcRootTracker.visit_nop
+    visit_int = FunctionGcRootTracker32.visit_nop
     # probably not GC pointers
-    visit_cdq  = FunctionGcRootTracker.visit_nop
+    visit_cdq  = FunctionGcRootTracker32.visit_nop
 
     def visit_npad(self, line):
         # MASM has a nasty bug: it implements "npad 5" with "add eax, 0"
@@ -1038,7 +1302,7 @@
         table = tracker.computegcmaptable(self.verbose)
         if self.verbose > 1:
             for label, state in table:
-                print >> sys.stderr, label, '\t', format_callshape(state)
+                print >> sys.stderr, label, '\t', tracker.format_callshape(state)
         table = compress_gcmaptable(table)
         if self.shuffle and random.random() < 0.5:
             self.gcmaptable[:0] = table
@@ -1049,7 +1313,7 @@
 
 class ElfAssemblerParser(AssemblerParser):
     format = "elf"
-    FunctionGcRootTracker = ElfFunctionGcRootTracker
+    FunctionGcRootTracker = ElfFunctionGcRootTracker32
 
     def find_functions(self, iterlines):
         functionlines = []
@@ -1072,6 +1336,10 @@
             "missed the end of the previous function")
         yield False, functionlines
 
+class ElfAssemblerParser64(ElfAssemblerParser):
+    format = "elf64"
+    FunctionGcRootTracker = ElfFunctionGcRootTracker64
+
 class DarwinAssemblerParser(AssemblerParser):
     format = "darwin"
     FunctionGcRootTracker = DarwinFunctionGcRootTracker
@@ -1241,6 +1509,7 @@
 
 PARSERS = {
     'elf': ElfAssemblerParser,
+    'elf64': ElfAssemblerParser64,
     'darwin': DarwinAssemblerParser,
     'mingw32': Mingw32AssemblerParser,
     'msvc': MsvcAssemblerParser,
@@ -1281,6 +1550,13 @@
             txt = kwargs[self.format]
             print >> output, "\t%s" % txt
 
+        if self.format == 'elf64':
+            word_decl = '.quad'
+        else:
+            word_decl = '.long'
+
+        tracker_cls = PARSERS[self.format].FunctionGcRootTracker
+
         # The pypy_asm_stackwalk() function
 
         if self.format == 'msvc':
@@ -1327,7 +1603,56 @@
                }
             }
             """
+        elif self.format == 'elf64':
+            print >> output, "\t.text"
+            print >> output, "\t.globl %s" % _globalname('pypy_asm_stackwalk')
+            print >> output, "\t.type pypy_asm_stackwalk, @function"
+            print >> output, "%s:" % _globalname('pypy_asm_stackwalk')
+
+            print >> output, """\
+            /* See description in asmgcroot.py */
+            movq\t%rdi, %rdx\t/* 1st argument, which is the callback */
+            movq\t%rsi, %rcx\t/* 2nd argument, which is gcrootanchor */
+            movq\t%rsp, %rax\t/* my frame top address */
+            pushq\t%rax\t\t/* ASM_FRAMEDATA[8] */
+            pushq\t%rbp\t\t/* ASM_FRAMEDATA[7] */
+            pushq\t%r15\t\t/* ASM_FRAMEDATA[6] */
+            pushq\t%r14\t\t/* ASM_FRAMEDATA[5] */
+            pushq\t%r13\t\t/* ASM_FRAMEDATA[4] */
+            pushq\t%r12\t\t/* ASM_FRAMEDATA[3] */
+            pushq\t%rbx\t\t/* ASM_FRAMEDATA[2] */
+
+            /* Add this ASM_FRAMEDATA to the front of the circular linked */
+            /* list.  Let's call it 'self'.                               */
 
+            movq\t8(%rcx), %rax\t/* next = gcrootanchor->next */
+            pushq\t%rax\t\t\t\t/* self->next = next */
+            pushq\t%rcx\t\t\t/* self->prev = gcrootanchor */
+            movq\t%rsp, 8(%rcx)\t/* gcrootanchor->next = self */
+            movq\t%rsp, 0(%rax)\t\t\t/* next->prev = self */
+
+            /* note: the Mac OS X 16 bytes aligment must be respected. */
+            call\t*%rdx\t\t/* invoke the callback */
+
+            /* Detach this ASM_FRAMEDATA from the circular linked list */
+            popq\t%rsi\t\t/* prev = self->prev */
+            popq\t%rdi\t\t/* next = self->next */
+            movq\t%rdi, 8(%rsi)\t/* prev->next = next */
+            movq\t%rsi, 0(%rdi)\t/* next->prev = prev */
+
+            popq\t%rbx\t\t/* restore from ASM_FRAMEDATA[2] */
+            popq\t%r12\t\t/* restore from ASM_FRAMEDATA[3] */
+            popq\t%r13\t\t/* restore from ASM_FRAMEDATA[4] */
+            popq\t%r14\t\t/* restore from ASM_FRAMEDATA[5] */
+            popq\t%r15\t\t/* restore from ASM_FRAMEDATA[6] */
+            popq\t%rbp\t\t/* restore from ASM_FRAMEDATA[7] */
+            popq\t%rcx\t\t/* ignored      ASM_FRAMEDATA[8] */
+
+            /* 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
+            """
         else:
             print >> output, "\t.text"
             print >> output, "\t.globl %s" % _globalname('pypy_asm_stackwalk')
@@ -1401,7 +1726,7 @@
                     n = shapes[state]
                 except KeyError:
                     n = shapes[state] = shapeofs
-                    bytes = [str(b) for b in compress_callshape(state)]
+                    bytes = [str(b) for b in tracker_cls.compress_callshape(state)]
                     shapelines.append('\t%s,\t/* %s */\n' % (
                             ', '.join(bytes),
                             shapeofs))
@@ -1433,17 +1758,18 @@
                     n = shapes[state]
                 except KeyError:
                     n = shapes[state] = shapeofs
-                    bytes = [str(b) for b in compress_callshape(state)]
+                    bytes = [str(b) for b in tracker_cls.compress_callshape(state)]
                     shapelines.append('\t/*%d*/\t.byte\t%s\n' % (
                         shapeofs,
                         ', '.join(bytes)))
                     shapeofs += len(bytes)
                 if is_range:
                     n = ~ n
-                print >> output, '\t.long\t%s-%d' % (
+                print >> output, '\t%s\t%s-%d' % (
+                    word_decl,
                     label,
-                    PARSERS[self.format].FunctionGcRootTracker.OFFSET_LABELS)
-                print >> output, '\t.long\t%d' % (n,)
+                    tracker_cls.OFFSET_LABELS)
+                print >> output, '\t%s\t%d' % (word_decl, n)
 
             print >> output, """\
             .globl __gcmapend
@@ -1451,6 +1777,7 @@
             """.replace("__gcmapend", _globalname("__gcmapend"))
 
             _variant(elf='.section\t.rodata',
+                     elf64='.section\t.rodata',
                      darwin='.const',
                      mingw32='')
 
@@ -1483,56 +1810,6 @@
     pass
 
 
-# __________ debugging output __________
-
-def format_location(loc):
-    # A 'location' is a single number describing where a value is stored
-    # across a call.  It can be in one of the CALLEE_SAVE_REGISTERS, or
-    # in the stack frame at an address relative to either %esp or %ebp.
-    # The last two bits of the location number are used to tell the cases
-    # apart; see format_location().
-    assert loc >= 0
-    kind = loc & LOC_MASK
-    if kind == LOC_REG:
-        if loc == LOC_NOWHERE:
-            return '?'
-        reg = (loc >> 2) - 1
-        return ElfFunctionGcRootTracker.CALLEE_SAVE_REGISTERS[reg]
-    else:
-        offset = loc & ~ LOC_MASK
-        if kind == LOC_EBP_PLUS:
-            result = '(%ebp)'
-        elif kind == LOC_EBP_MINUS:
-            result = '(%ebp)'
-            offset = -offset
-        elif kind == LOC_ESP_PLUS:
-            result = '(%esp)'
-        else:
-            assert 0, kind
-        if offset != 0:
-            result = str(offset) + result
-        return result
-
-def format_callshape(shape):
-    # A 'call shape' is a tuple of locations in the sense of format_location().
-    # They describe where in a function frame interesting values are stored,
-    # when this function executes a 'call' instruction.
-    #
-    #   shape[0] is the location that stores the fn's own return address
-    #            (not the return address for the currently executing 'call')
-    #   shape[1] is where the fn saved its own caller's %ebx value
-    #   shape[2] is where the fn saved its own caller's %esi value
-    #   shape[3] is where the fn saved its own caller's %edi value
-    #   shape[4] is where the fn saved its own caller's %ebp value
-    #   shape[>=5] are GC roots: where the fn has put its local GCPTR vars
-    #
-    assert isinstance(shape, tuple)
-    assert len(shape) >= 5
-    result = [format_location(loc) for loc in shape]
-    return '{%s | %s | %s}' % (result[0],
-                               ', '.join(result[1:5]),
-                               ', '.join(result[5:]))
-
 # __________ table compression __________
 
 def compress_gcmaptable(table):
@@ -1559,49 +1836,6 @@
         yield (label1, state, is_range)
         i = j
 
-def compress_callshape(shape):
-    # For a single shape, this turns the list of integers into a list of
-    # bytes and reverses the order of the entries.  The length is
-    # encoded by inserting a 0 marker after the gc roots coming from
-    # shape[5:] and before the 5 values coming from shape[4] to
-    # shape[0].  In practice it seems that shapes contain many integers
-    # whose value is up to a few thousands, which the algorithm below
-    # compresses down to 2 bytes.  Very small values compress down to a
-    # single byte.
-    assert len(shape) >= 5
-    shape = list(shape)
-    assert 0 not in shape[5:]
-    shape.insert(5, 0)
-    result = []
-    for loc in shape:
-        assert loc >= 0
-        flag = 0
-        while loc >= 0x80:
-            result.append(int(loc & 0x7F) | flag)
-            flag = 0x80
-            loc >>= 7
-        result.append(int(loc) | flag)
-    result.reverse()
-    return result
-
-def decompress_callshape(bytes):
-    # For tests.  This logic is copied in asmgcroot.py.
-    result = []
-    n = 0
-    while n < len(bytes):
-        value = 0
-        while True:
-            b = bytes[n]
-            n += 1
-            value += b
-            if b < 0x80:
-                break
-            value = (value - 0x80) << 7
-        result.append(value)
-    result.reverse()
-    assert result[5] == 0
-    del result[5]
-    return result
 
 def getidentifier(s):
     def mapchar(c):
@@ -1626,7 +1860,10 @@
     elif sys.platform == 'win32':
         format = 'mingw32'
     else:
-        format = 'elf'
+        if sys.maxint > 2147483647:
+            format = 'elf64'
+        else:
+            format = 'elf'
     entrypoint = 'main'
     while len(sys.argv) > 1:
         if sys.argv[1] == '-v':

Modified: pypy/branch/jit-bounds/pypy/translator/platform/linux.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/translator/platform/linux.py	(original)
+++ pypy/branch/jit-bounds/pypy/translator/platform/linux.py	Thu Sep  9 18:10:18 2010
@@ -3,7 +3,7 @@
 from pypy.translator.platform import _run_subprocess
 from pypy.translator.platform.posix import BasePosix
 
-class Linux(BasePosix):
+class BaseLinux(BasePosix):
     name = "linux"
     
     link_flags = ('-pthread', '-lrt')
@@ -25,10 +25,12 @@
         return self._pkg_config("libffi", "--libs-only-L",
                                 ['/usr/lib/libffi'])
 
+
+class Linux(BaseLinux):
     def library_dirs_for_libffi_a(self):
         # places where we need to look for libffi.a
         return self.library_dirs_for_libffi() + ['/usr/lib']
 
 
-class Linux64(Linux):
-    shared_only = ('-fPIC',)
+class Linux64(BaseLinux):
+    pass

Modified: pypy/branch/jit-bounds/pypy/translator/platform/posix.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/translator/platform/posix.py	(original)
+++ pypy/branch/jit-bounds/pypy/translator/platform/posix.py	Thu Sep  9 18:10:18 2010
@@ -4,7 +4,7 @@
 
 from pypy.translator.platform import Platform, log, _run_subprocess
 from pypy.tool import autopath
-import py, os
+import py, os, sys
 
 class BasePosix(Platform):
     exe_ext = ''
@@ -104,6 +104,13 @@
         else:
             target_name = exe_name.basename
 
+        cflags = self.cflags
+        if sys.maxint > 2147483647:   # XXX XXX XXX sort this out
+            if shared:
+                cflags = self.cflags + self.shared_only
+            else:
+                cflags = self.cflags + self.standalone_only
+
         m = GnuMakefile(path)
         m.exe_name = exe_name
         m.eci = eci
@@ -132,7 +139,7 @@
             ('LIBS', self._libs(eci.libraries)),
             ('LIBDIRS', self._libdirs(eci.library_dirs)),
             ('INCLUDEDIRS', self._includedirs(rel_includedirs)),
-            ('CFLAGS', self.cflags),
+            ('CFLAGS', cflags),
             ('CFLAGSEXTRA', list(eci.compile_extra)),
             ('LDFLAGS', linkflags),
             ('LDFLAGSEXTRA', list(eci.link_extra)),



More information about the Pypy-commit mailing list