1. 06 Jul, 2002 4 commits
  2. 05 Jul, 2002 1 commit
  3. 04 Jul, 2002 4 commits
  4. 03 Jul, 2002 7 commits
  5. 02 Jul, 2002 20 commits
  6. 01 Jul, 2002 2 commits
    • Fred Drake's avatar
      7c75bf20
    • Tim Peters's avatar
      OK, I couldn't stand it <0.5 wink>: removed all uncertainty about what's · 19b74c78
      Tim Peters authored
      in gc_refs, even at the cost of putting back a test+branch in
      visit_decref.
      
      The good news:  since gc_refs became utterly tame then, it became
      clear that another special value could be useful.  The move_roots() and
      move_root_reachable() passes have now been replaced by a single
      move_unreachable() pass.  Besides saving a pass over the generation, this
      has a better effect:  most of the time everything turns out to be
      reachable, so we were breaking the generation list apart and moving it
      into into the reachable list, one element at a time.  Now the reachable
      stuff stays in the generation list, and the unreachable stuff is moved
      instead.  This isn't quite as good as it sounds, since sometimes we
      guess wrongly that a thing is unreachable, and have to move it back again.
      
      Still, overall, it yields a significant (but not dramatic) boost in
      collection speed.
      19b74c78
  7. 30 Jun, 2002 2 commits
    • Tim Peters's avatar
      visit_decref(): Two optimizations. · 93cd83e4
      Tim Peters authored
      1. You're not supposed to call this with a NULL argument, although the
         docs could be clearer about that.  The other visit_XYZ() functions
         don't bother to check.  This doesn't either now, although it does
         assert non-NULL-ness now.
      
      2. It doesn't matter whether the object is currently tracked, so don't
         bother checking that either (if it isn't currently tracked, it may
         have some nonsense value in gc_refs, but it doesn't hurt to
         decrement gibberish, and it's cheaper to do so than to make everyone
         test for trackedness).
      
      It would be nice to get rid of the other tests on IS_TRACKED.  Perhaps
      trackedness should not be a matter of not being in any gc list, but
      should be a matter of being in a new "untracked" gc list.  This list
      simply wouldn't be involved in the collection mechanism.  A newly
      created object would be put in the untracked list.  Tracking would
      simply unlink it and move it into the gen0 list.  Untracking would do
      the reverse.  No test+branch needed then.  visit_move() may be vulnerable
      then, though, and I don't know how this would work with the trashcan.
      93cd83e4
    • Tim Peters's avatar
      SF bug #574132: Major GC related performance regression · 8839617c
      Tim Peters authored
      "The regression" is actually due to that 2.2.1 had a bug that prevented
      the regression (which isn't a regression at all) from showing up.  "The
      regression" is actually a glitch in cyclic gc that's been there forever.
      
      As the generation being collected is analyzed, objects that can't be
      collected (because, e.g., we find they're externally referenced, or
      are in an unreachable cycle but have a __del__ method) are moved out
      of the list of candidates.  A tricksy scheme uses negative values of
      gc_refs to mark such objects as being moved.  However, the exact
      negative value set at the start may become "more negative" over time
      for objects not in the generation being collected, and the scheme was
      checking for an exact match on the negative value originally assigned.
      As a result, objects in generations older than the one being collected
      could get scanned too, and yanked back into a younger generation.  Doing
      so doesn't lead to an error, but doesn't do any good, and can burn an
      unbounded amount of time doing useless work.
      
      A test case is simple (thanks to Kevin Jacobs for finding it!):
      
      x = []
      for i in xrange(200000):
          x.append((1,))
      
      Without the patch, this ends up scanning all of x on every gen0 collection,
      scans all of x twice on every gen1 collection, and x gets yanked back into
      gen1 on every gen0 collection.  With the patch, once x gets to gen2, it's
      never scanned again until another gen2 collection, and stays in gen2.
      
      Bugfix candidate, although the code has changed enough that I think I'll
      need to port it by hand.  2.2.1 also has a different bug that causes
      bound method objects not to get tracked at all (so the test case doesn't
      burn absurd amounts of time in 2.2.1, but *should* <wink>).
      8839617c