[pypy-svn] pypy jit-lsprofile: (alex, fijal): Encoding read_timestamp in x86.

alex_gaynor commits-noreply at bitbucket.org
Sun Mar 13 21:05:04 CET 2011


Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: jit-lsprofile
Changeset: r42574:9f792994603c
Date: 2011-03-13 16:04 -0400
http://bitbucket.org/pypy/pypy/changeset/9f792994603c/

Log:	(alex, fijal): Encoding read_timestamp in x86.

diff --git a/pypy/jit/backend/x86/rx86.py b/pypy/jit/backend/x86/rx86.py
--- a/pypy/jit/backend/x86/rx86.py
+++ b/pypy/jit/backend/x86/rx86.py
@@ -400,12 +400,12 @@
 
 
 # Method names take the form of
-# 
+#
 #     <instruction name>_<operand type codes>
 #
 # For example, the method name for "mov reg, immed" is MOV_ri. Operand order
 # is Intel-style, with the destination first.
-# 
+#
 # The operand type codes are:
 #     r - register
 #     b - ebp/rbp offset
@@ -540,6 +540,9 @@
     # x87 instructions
     FSTP_b = insn('\xDD', orbyte(3<<3), stack_bp(1))
 
+    # ------------------------------ Random mess -----------------------
+    RDTSC = insn('\x0F\x31')
+
     # ------------------------------ SSE2 ------------------------------
 
     # Conversion

diff --git a/pypy/jit/backend/x86/assembler.py b/pypy/jit/backend/x86/assembler.py
--- a/pypy/jit/backend/x86/assembler.py
+++ b/pypy/jit/backend/x86/assembler.py
@@ -301,7 +301,7 @@
         if log:
             self._register_counter()
             operations = self._inject_debugging_code(looptoken, operations)
-        
+
         regalloc = RegAlloc(self, self.cpu.translate_support_code)
         arglocs = regalloc.prepare_loop(inputargs, operations, looptoken)
         looptoken._x86_arglocs = arglocs
@@ -310,7 +310,7 @@
         stackadjustpos = self._assemble_bootstrap_code(inputargs, arglocs)
         self.looppos = self.mc.get_relative_pos()
         looptoken._x86_frame_depth = -1     # temporarily
-        looptoken._x86_param_depth = -1     # temporarily        
+        looptoken._x86_param_depth = -1     # temporarily
         frame_depth, param_depth = self._assemble(regalloc, operations)
         looptoken._x86_frame_depth = frame_depth
         looptoken._x86_param_depth = param_depth
@@ -509,7 +509,7 @@
 
     def _assemble(self, regalloc, operations):
         self._regalloc = regalloc
-        regalloc.walk_operations(operations)        
+        regalloc.walk_operations(operations)
         if we_are_translated() or self.cpu.dont_keepalive_stuff:
             self._regalloc = None   # else keep it around for debugging
         frame_depth = regalloc.fm.frame_depth
@@ -957,7 +957,7 @@
                     dst_locs.append(unused_gpr.pop())
                 else:
                     pass_on_stack.append(loc)
-        
+
         # Emit instructions to pass the stack arguments
         # XXX: Would be nice to let remap_frame_layout take care of this, but
         # we'd need to create something like StackLoc, but relative to esp,
@@ -1363,6 +1363,15 @@
         else:
             assert 0, itemsize
 
+    def genop_read_timestamp(self, op, arglocs, resloc):
+        # XXX cheat
+        addr1 = self.fail_boxes_int.get_addr_for_num(0)
+        addr2 = self.fail_boxes_int.get_addr_for_num(1)
+        self.mc.RDTSC()
+        self.mc.MOV(heap(addr1), eax)
+        self.mc.MOV(heap(addr2), edx)
+        self.mc.MOVSD(resloc, heap(addr1))
+
     def genop_guard_guard_true(self, ign_1, guard_op, guard_token, locs, ign_2):
         loc = locs[0]
         self.mc.TEST(loc, loc)
@@ -1796,7 +1805,7 @@
             tmp = ecx
         else:
             tmp = eax
-        
+
         self._emit_call(x, arglocs, 3, tmp=tmp)
 
         if IS_X86_32 and isinstance(resloc, StackLoc) and resloc.width == 8:
@@ -2040,7 +2049,7 @@
         # on 64-bits, 'tid' is a value that fits in 31 bits
         self.mc.MOV_mi((eax.value, 0), tid)
         self.mc.MOV(heap(nursery_free_adr), edx)
-        
+
 genop_discard_list = [Assembler386.not_implemented_op_discard] * rop._LAST
 genop_list = [Assembler386.not_implemented_op] * rop._LAST
 genop_llong_list = {}
@@ -2051,7 +2060,7 @@
         opname = name[len('genop_discard_'):]
         num = getattr(rop, opname.upper())
         genop_discard_list[num] = value
-    elif name.startswith('genop_guard_') and name != 'genop_guard_exception': 
+    elif name.startswith('genop_guard_') and name != 'genop_guard_exception':
         opname = name[len('genop_guard_'):]
         num = getattr(rop, opname.upper())
         genop_guard_list[num] = value

diff --git a/pypy/jit/metainterp/test/test_basic.py b/pypy/jit/metainterp/test/test_basic.py
--- a/pypy/jit/metainterp/test/test_basic.py
+++ b/pypy/jit/metainterp/test/test_basic.py
@@ -2233,10 +2233,19 @@
         self.check_tree_loop_count(2)
 
     def test_read_timestamp(self):
-        from pypy.rlib.test.test_rtimer import timer
+        import time
+        from pypy.rlib.rtimer import read_timestamp
+        def busy_loop():
+            start = time.time()
+            while time.time() - start < 0.1:
+                # busy wait
+                pass
+
         def f():
-            diff = timer()
-            return diff > 1000
+            t1 = read_timestamp()
+            busy_loop()
+            t2 = read_timestamp()
+            return t2 - t1 > 1000
         res = self.interp_operations(f, [])
         assert res
 

diff --git a/pypy/jit/backend/llgraph/llimpl.py b/pypy/jit/backend/llgraph/llimpl.py
--- a/pypy/jit/backend/llgraph/llimpl.py
+++ b/pypy/jit/backend/llgraph/llimpl.py
@@ -25,6 +25,7 @@
 from pypy.rlib.objectmodel import ComputedIntSymbolic, we_are_translated
 from pypy.rlib.rarithmetic import ovfcheck
 from pypy.rlib.rarithmetic import r_longlong, r_ulonglong, r_uint
+from pypy.rlib.rtimer import c_read_timestamp
 
 import py
 from pypy.tool.ansi_print import ansi_log
@@ -506,7 +507,7 @@
                         ', '.join(map(str, args)),))
                 self.fail_args = args
                 return op.fail_index
- 
+
             else:
                 assert 0, "unknown final operation %d" % (op.opnum,)
 
@@ -856,6 +857,9 @@
         opaque_frame = _to_opaque(self)
         return llmemory.cast_ptr_to_adr(opaque_frame)
 
+    def op_read_timestamp(self, descr):
+        return c_read_timestamp()
+
     def op_call_may_force(self, calldescr, func, *args):
         assert not self._forced
         self._may_force = self.opindex
@@ -937,7 +941,7 @@
 class OOFrame(Frame):
 
     OPHANDLERS = [None] * (rop._LAST+1)
-    
+
     def op_new_with_vtable(self, descr, vtable):
         assert descr is None
         typedescr = get_class_size(self.memocast, vtable)
@@ -958,7 +962,7 @@
         return res
 
     op_getfield_gc_pure = op_getfield_gc
-    
+
     def op_setfield_gc(self, fielddescr, obj, newvalue):
         TYPE = fielddescr.TYPE
         fieldname = fielddescr.fieldname

diff --git a/pypy/jit/backend/x86/regalloc.py b/pypy/jit/backend/x86/regalloc.py
--- a/pypy/jit/backend/x86/regalloc.py
+++ b/pypy/jit/backend/x86/regalloc.py
@@ -138,7 +138,7 @@
             xmm_reg_mgr_cls = X86_64_XMMRegisterManager
         else:
             raise AssertionError("Word size should be 4 or 8")
-            
+
         self.rm = gpr_reg_mgr_cls(longevity,
                                   frame_manager = self.fm,
                                   assembler = self.assembler)
@@ -341,7 +341,7 @@
         self.assembler.regalloc_perform_guard(guard_op, faillocs, arglocs,
                                               result_loc,
                                               current_depths)
-        self.possibly_free_vars(guard_op.getfailargs())        
+        self.possibly_free_vars(guard_op.getfailargs())
 
     def PerformDiscard(self, op, arglocs):
         if not we_are_translated():
@@ -417,7 +417,7 @@
                     assert isinstance(arg, Box)
                     if arg not in last_used:
                         last_used[arg] = i
-                        
+
         longevity = {}
         for arg in produced:
             if arg in last_used:
@@ -807,7 +807,7 @@
         self._call(op, [imm(size), vable] +
                    [self.loc(op.getarg(i)) for i in range(op.numargs())],
                    guard_not_forced_op=guard_op)
-        
+
     def consider_cond_call_gc_wb(self, op):
         assert op.result is None
         args = op.getarglist()
@@ -1156,6 +1156,16 @@
         else:
             raise AssertionError("bad unicode item size")
 
+    def consider_read_timestamp(self, op):
+        tmpbox_high = TempBox()
+        tmpbox_low = TempBox()
+        self.rm.force_allocate_reg(tmpbox_high, selected_reg=eax)
+        self.rm.force_allocate_reg(tmpbox_low, selected_reg=edx)
+        result_loc = self.xrm.force_allocate_reg(op.result)
+        self.Perform(op, [], result_loc)
+        self.rm.possibly_free_var(tmpbox_high)
+        self.rm.possibly_free_var(tmpbox_low)
+
     def consider_jump(self, op):
         assembler = self.assembler
         assert self.jump_target_descr is None
@@ -1172,13 +1182,13 @@
         xmmtmploc = self.xrm.force_allocate_reg(box1, selected_reg=xmmtmp)
         # Part about non-floats
         # XXX we don't need a copy, we only just the original list
-        src_locations = [self.loc(op.getarg(i)) for i in range(op.numargs()) 
+        src_locations = [self.loc(op.getarg(i)) for i in range(op.numargs())
                          if op.getarg(i).type != FLOAT]
         assert tmploc not in nonfloatlocs
         dst_locations = [loc for loc in nonfloatlocs if loc is not None]
         remap_frame_layout(assembler, src_locations, dst_locations, tmploc)
         # Part about floats
-        src_locations = [self.loc(op.getarg(i)) for i in range(op.numargs()) 
+        src_locations = [self.loc(op.getarg(i)) for i in range(op.numargs())
                          if op.getarg(i).type == FLOAT]
         dst_locations = [loc for loc in floatlocs if loc is not None]
         remap_frame_layout(assembler, src_locations, dst_locations, xmmtmp)


More information about the Pypy-commit mailing list