[pypy-svn] r67082 - pypy/branch/pyjitpl5/pypy/jit/metainterp/doc

benjamin at codespeak.net benjamin at codespeak.net
Fri Aug 21 17:42:12 CEST 2009


Author: benjamin
Date: Fri Aug 21 17:42:12 2009
New Revision: 67082

Modified:
   pypy/branch/pyjitpl5/pypy/jit/metainterp/doc/jitpl5.txt
   pypy/branch/pyjitpl5/pypy/jit/metainterp/doc/linking.txt
   pypy/branch/pyjitpl5/pypy/jit/metainterp/doc/virtualizables.txt
Log:
update, mostly by deleting things I know aren't true anymore

Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/doc/jitpl5.txt
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/doc/jitpl5.txt	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/doc/jitpl5.txt	Fri Aug 21 17:42:12 2009
@@ -12,20 +12,20 @@
 
 Tracing: executing code and recording what we did, for one loop.  This
 starts at the app-level JUMP_ABSOLUTE (or equivalent) bytecode that
-closes an app-level loop.  Implemented by interpreting the rainbow
+closes an app-level loop.  Implemented by interpreting a custom
 bytecode that describes the interpreter itself.  (Could later be
 optimized by removing the rainbow bytecode.)
 
 We pass around BoxInt and BoxPtr objects that have this minimal
 content::
 
-   +- BoxPtr ---------+
+   +- BoxInt ---------+
    |    real value    |
    +------------------+
 
-In other words, BoxInt and BoxPtr just record the real value.  Each
-operation generates a new BoxInt or BoxPtr (even if it contains the same
-real value as another box).
+In other words, BoxInt and BoxPtr just record the real value.  Like
+PyPy's flowgraph, each operation generates a new BoxInt or BoxPtr
+(even if it contains the same real value as another box).
 
 Tracing goes on for exactly one iteration of the app-level loop.  As it
 handles real values, it makes the real program progress one iteration.
@@ -95,9 +95,11 @@
 =============
 
 When a guard fails, we normally fall back to regular interpretation.
-Because the guard failure occurs in the middle of executing an app-level
-bytecode, this requires interpreting the rainbow bytecode with a
-fall-back interpreter until the start of the next app-level bytecode.
+Because the guard failure occurs in the middle of executing an
+app-level bytecode, this requires interpreting the bytecode describing
+the interpreter with a fall-back interpreter (which is actually
+implemented with the same code as the tracer) until the start of the
+next app-level bytecode.
 
 When we decide instead to compile more code for this guard failure, we
 take the set of live values and put them back into boxes, and proceed

Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/doc/linking.txt
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/doc/linking.txt	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/doc/linking.txt	Fri Aug 21 17:42:12 2009
@@ -25,33 +25,9 @@
            so that it points to the next bytecode to execute */
     }
 
-Initially, for a given frame position, there is no machine code produced
-by the JIT so far.  To simplify things, we use the following trick:
-conceptually there is *always* machine code available, but this machine
-code just contains an always-failing guard.  So
-lookup_machine_code_for() returns a pointer to machine code that looks
-like this::
-
-    setup the frame...
-    /* here starts the code for an always- failing guard */
-    PUSH info_about_this_guard
-    JMP generic_guard_recovery_code
-
-The generic guard recovery code contains the following logic::
-
-    REG1 = info_about_this_guard
-    REG2 = current_stack_base_pointer
-    REG3 = CALL jit_compile(REG1, REG2)
-    copy REG3->inputargs[0] to EAX
-    copy REG3->inputargs[1] to EBX
-    etc.
-    JMP REG3->targetaddr
-
-The jit_compile() function comes from RPython sources written in the JIT
-support code.  It does tracing and generally ends up compiling an extra
-loop to machine code.  It can also patch the failing guard in the
-machine code (above) so that later invocations will jump directly to the
-correct code.
+The jit_compile() function comes from RPython sources written in the
+JIT support code (warmspot.py).  It does tracing and generally ends up
+compiling an extra loop to machine code.
 
 Then jit_compile() itself needs to transfer execution to the newly
 compiled loop.  Instead of calling the loop, jit_compile() returns a

Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/doc/virtualizables.txt
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/doc/virtualizables.txt	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/doc/virtualizables.txt	Fri Aug 21 17:42:12 2009
@@ -57,48 +57,3 @@
 We can achieve that by unpacking W_IntObject read from locals before the loop
 and carefully rebuilding this for each guard failure, by a small bit of
 assembler code.
-
-Problem one: what if we access this from a call or somewhere else?
--------------------------------------------------------------------
-
-This is the general problem with virtualizables, what if one has a reference
-to that object and will choose to use it in place where we have things on
-stack or not allocated at all?
-
-1. We store a small piece of assembler code as a function pointer inside
-   a virtualizable. This is, I think, simpler than having complex rebuild
-   info kept together along the chain. If someone accesses the frame,
-   this code will run and rebuild what is necessary. If this happens, there
-   are two possiblities:
-
-2. We check after the call (guard_nonvirtualized, but we need to put it
-   a bit differently) that frame was not accessed and if it was, exit the
-   jit.
-
-Problem two: what if we grow more elements during bridges?
-----------------------------------------------------------
-
-The problem is for such code:
-
-  while i < 10000:
-    if i % 2:
-     i += a
-    else:
-     i += b
-
-Now the first loop is compiled and when the second part (a bridge) is compiled,
-we end up with non-matching virtualizables. To avoid that, we need to pass
-more arguments to the loop that usually anticipated. Note that this is not
-a big deal if we're careful enough (for x86) since we can put more stuff on
-the stack if we update esp register. We'll use ebp as a base for stack
-operations, so we're free to change value of esp any time we want.
-So we will end up with things like this:
-
-(%ebp-4), (%ebp-8), (%ebp-c) - original args
-(%ebp-10), %(ebp-14) - temporary values
-(%ebp-18) - additional value
-
-and we'll update esp by +4
-
-This also solves the problem of moving around vars when we need to update
-esp because of jump. good.



More information about the Pypy-commit mailing list