Commits

Armin Rigo committed dbb536d

Speed up allocation by leaving the value of h_revision undefined.
Also allows the GC the abuse this h_revision as it wants on newly
allocated objects (e.g. on all nursery objects).

Comments (0)

Files changed (1)

talk/stm2012/stmimpl.rst

 - h_global (boolean)
 - h_possibly_outdated (boolean)
 - h_written (boolean)
+- h_local_copy (boolean)
 - h_revision (unsigned integer)
 
 The h_revision is an unsigned "revision number" that can also
   version in any transaction.
 
 - ``h_written`` is set on local objects that have been written to.
+  It is false on global objects.
+
+- ``h_local_copy`` is set on local objects that are a copy of a global
+  object.  It is undefined on global objects.
 
 - ``h_revision`` on local objects points to the global object that they
-  come from, if any; otherwise it is 1.
+  come from, if any (i.e. if ``h_local_copy``); otherwise it is
+  undefined (and can be used for other purposes, e.g. by the GC).
 
 - ``h_revision`` on global objects depends on whether the object is the
   head of the chained list of revisions or not.  If it is, then
 
 - All barriers ensure that ``global_to_local`` satisfies the following
   property for any local object ``L``: either ``L`` was created by
-  this transaction (``L->h_revision == 1``) or else satisfies
+  this transaction (``L->h_revision`` is undefined) or else satisfies
   ``global_to_local[L->h_revision] == L``.
 
 
         W->h_global = False
         W->h_possibly_outdated = False
         W->h_written = True
-        W->h_revision = 1
+        W->h_local_copy = False
+        #W->h_revision can be left uninitialized
         return W
 
 
         L->h_global = False
         L->h_possibly_outdated = False
         L->h_written = False
+        L->h_local_copy = True
         L->h_revision = R          # back-reference to the original
         L->objectbody... = R->objectbody...
         global_to_local[R] = L
         collect from the roots...
         for all reached local object,
             change h_global False->True
-            and h_written True->False
+            change h_written True->False
+            if not h_local_copy:
+                h_revision = 1
 
 Note that non-written local objects are just shadow copies of existing
 global objects.  For the sequel we just replace them with the original
 global objects again.  This is done by tweaking the local objects'
 header.
 
+Note also that ``h_revision`` is free to be (ab)used on newly allocated
+objects (the GC of PyPy does this), but it should be set to 1 just
+before calling ``CommitTransaction``.
+
 
 Committing
 ------------------------------------
             return NULL
         elif P->h_global:
             return LatestGlobalRevision(P)
-        elif P->h_revision != 1:
+        elif P->h_local_copy:
             return P->h_revision  # return the original global obj
         else:
-            return P              # local, allocated during this transaction
+            return P