summaryrefslogtreecommitdiffstats
path: root/Modules/gcmodule.c
Commit message (Collapse)AuthorAgeFilesLines
...
* handle_weakrefs(): Simplification -- there's no need to make a secondTim Peters2004-10-311-58/+28
| | | | pass over the unreachable weakrefs-with-callbacks to unreachable objects.
* SF 1055820: weakref callback vs gc vs threadsTim Peters2004-10-301-106/+183
| | | | | | | | In cyclic gc, clear weakrefs to unreachable objects before allowing any Python code (weakref callbacks or __del__ methods) to run. This is a critical bugfix, affecting all versions of Python since weakrefs were introduced. I'll backport to 2.3.
* Convert return value to boolean.Raymond Hettinger2004-01-041-1/+1
|
* Silence GCC warning when asserts are turned off.Guido van Rossum2003-11-241-2/+1
|
* SF bug 839548: Bug in type's GC handling causes segfaults.Tim Peters2003-11-201-13/+129
| | | | | | | | Also SF patch 843455. This is a critical bugfix. I'll backport to 2.3 maint, but not beyond that. The bugs this fixes have been there since weakrefs were introduced.
* update_refs(): assert that incoming refcounts aren't 0. The commentTim Peters2003-11-141-0/+19
| | | | | | | | for this function has always claimed that was true, but it wasn't verified before. For the latest batch of "double deallocation" bugs (stemming from weakref callbacks invoked by way of subtype_dealloc), this assert would have triggered (instead of waiting for _Py_ForgetReference to die with a segfault later).
* Bug #794140: cygwin builds do not embedJason Tishler2003-09-041-1/+1
| | | | | | The embed2.diff patch solves the user's problem by exporting the missing symbols from the Python core so Python can be embedded in another Cygwin application (well, at lest vim).
* - New C API PyGC_Collect(), same as calling gc.collect().Guido van Rossum2003-04-171-1/+19
| | | | | - Call this in Py_Finalize(). - Expand the Misc/NEWS text on PY_LONG_LONG.
* s/referrents/referents/g. Gotta love that referrers remains rife with rs.Tim Peters2003-04-081-8/+8
|
* Finished implementing gc.get_referrents(): dealt with error and endTim Peters2003-04-081-6/+15
| | | | cases, wrote docs, added a test.
* Comment repair; no semantic changes.Tim Peters2003-04-071-4/+5
|
* Reworked has_finalizer() to use the new _PyObject_Lookup() insteadTim Peters2003-04-071-73/+45
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | of PyObject_HasAttr(); the former promises never to execute arbitrary Python code. Undid many of the changes recently made to worm around the worst consequences of that PyObject_HasAttr() could execute arbitrary Python code. Compatibility is hard to discuss, because the dangerous cases are so perverse, and much of this appears to rely on implementation accidents. To start with, using hasattr() to check for __del__ wasn't only dangerous, in some cases it was wrong: if an instance of an old- style class didn't have "__del__" in its instance dict or in any base class dict, but a getattr hook said __del__ existed, then hasattr() said "yes, this object has a __del__". But instance_dealloc() ignores the possibility of getattr hooks when looking for a __del__, so while object.__del__ succeeds, no __del__ method is called when the object is deleted. gc was therefore incorrect in believing that the object had a finalizer. The new method doesn't suffer that problem (like instance_dealloc(), _PyObject_Lookup() doesn't believe __del__ exists in that case), but does suffer a somewhat opposite-- and even more obscure --oddity: if an instance of an old-style class doesn't have "__del__" in its instance dict, and a base class does have "__del__" in its dict, and the first base class with a "__del__" associates it with a descriptor (an object with a __get__ method), *and* if that descriptor raises an exception when __get__ is called, then (a) the current method believes the instance does have a __del__, but (b) hasattr() does not believe the instance has a __del__. While these disagree, I believe the new method is "more correct": because the descriptor *will* be called when the object is destructed, it can execute arbitrary Python code at the time the object is destructed, and that's really what gc means by "has a finalizer": not specifically a __del__ method, but more generally the possibility of executing arbitrary Python code at object destruction time. Code in a descriptor's __get__() executed at destruction time can be just as problematic as code in a __del__() executed then. So I believe the new method is better on all counts. Bugfix candidate, but it's unclear to me how all this differs in the 2.2 branch (e.g., new-style and old-style classes already took different gc paths in 2.3 before this last round of patches, but don't in the 2.2 branch).
* initgc(): Rewrote to use the PyModule_AddXYZ API; cuts code size.Tim Peters2003-04-061-17/+14
|
* handle_finalizers(): Rewrote to call append_objects() and gc_list_merge()Tim Peters2003-04-061-36/+31
| | | | | | | | | instead of looping. Smaller and clearer. Faster, too, when we're not appending to gc.garbage: gc_list_merge() takes constant time, regardless of the lists' sizes. append_objects(): Moved up to live with the other list manipulation utilities.
* Switched from METH_VARARGS to METH_NOARGS for the 7 module functions thatTim Peters2003-04-061-44/+17
| | | | take no arguments; cuts generated code size.
* Reworked move_finalizer_reachable() to create two distinct lists:Tim Peters2003-04-061-31/+57
| | | | | | | | | externally unreachable objects with finalizers, and externally unreachable objects without finalizers reachable from such objects. This allows us to call has_finalizer() at most once per object, and so limit the pain of nasty getattr hooks. This fixes the failing "boom 2" example Jeremy posted (a non-printing variant of which is now part of test_gc), via never triggering the nasty part of its __getattr__ method.
* move_finalizers(): Rewrote. It's not necessary for this routineTim Peters2003-04-051-29/+20
| | | | | | | | | | | | | | to special-case classic classes, or to worry about refcounts; has_finalizer() deleted the current object iff the first entry in the unreachable list has changed. I don't believe it was correct to check for ob_refcnt == 1, either: the dealloc routine would get called by Py_DECREF then, but there's nothing to stop the dealloc routine from ressurecting the object, and then gc would remain at the head of the unreachable list despite that its refcount temporarily fell to 0 (and that would lead to an infinite loop in move_finalizers()). I'm still worried about has_finalizer() resurrecting other objects in the unreachable list: what's to stop them from getting collected?
* New comments. Rewrote has_finalizer() as a sequence of ifs instead ofTim Peters2003-04-051-6/+21
| | | | | | squashed-together conditional operators; makes it much easier to step thru in the debugger, and to set a breakpoint on the only dangerous path.
* Fixed new seemingly random segfaults, by moving the initialization ofTim Peters2003-04-051-8/+11
| | | | | | | | | | delstr from initgc() into collect(). initgc() isn't called unless the user explicitly imports gc, so can be used only for initialization of user-visible module features; delstr needs to be initialized for proper internal operation, whether or not gc is explicitly imported. Bugfix candidate? I don't know whether the new bug was backported to 2.2 already.
* Fix Tim's boom example.Jeremy Hylton2003-04-041-20/+54
| | | | | move_finalizers() moves every object from unreachable to collectable or finalizers, unless the object is deallocated first.
* Add get_referrents() helper function.Jeremy Hylton2003-04-031-1/+1
|
* Add get_referrents() helper function.Jeremy Hylton2003-04-031-1/+32
|
* Fix typo.Martin v. Löwis2002-11-091-1/+1
|
* For new-style classes, we can now test for tp_del instead of askingGuido van Rossum2002-08-091-3/+3
| | | | for a __del__ attribute, to see if there's a finalizer.
* Trashcan cleanup: Now that cyclic gc is always there, the trashcanTim Peters2002-07-071-0/+3
| | | | | | | | | | | | | | | | | | | mechanism is no longer evil: it no longer plays dangerous games with the type pointer or refcounts, and objects in extension modules can play along too without needing to edit the core first. Rewrote all the comments to explain this, and (I hope) give clear guidance to extension authors who do want to play along. Documented all the functions. Added more asserts (it may no longer be evil, but it's still dangerous <0.9 wink>). Rearranged the generated code to make it clearer, and to tolerate either the presence or absence of a semicolon after the macros. Rewrote _PyTrash_destroy_chain() to call tp_dealloc directly; it was doing a Py_DECREF again, and that has all sorts of obscure distorting effects in non-release builds (Py_DECREF was already called on the object!). Removed Christian's little "embedded change log" comments -- that's what checkin messages are for, and since it was impossible to correlate the comments with the code that changed, I found them merely distracting.
* Removed WITH_CYCLE_GC #ifdef-ery. Holes:Tim Peters2002-07-071-23/+0
| | | | | | + I'm not sure what to do about configure.in. Left it alone. + Ditto pyexpat.c. Fred or Martin will know what to do.
* gc_list_move defined but not used.Michael W. Hudson2002-07-041-15/+0
|
* visit_decref(): Added another assert.Tim Peters2002-07-021-0/+1
|
* Finished transitioning to using gc_refs to track gc objects' states.Tim Peters2002-07-021-39/+66
| | | | | | | This was mostly a matter of adding comments and light code rearrangement. Upon untracking, gc_next is still set to NULL. It's a cheap way to provoke memory faults if calling code is insane. It's also used in some way by the trashcan mechanism.
* Reserved another gc_refs value for untracked objects. Every live gcTim Peters2002-07-021-6/+16
| | | | | | | | | | | | object should now have a well-defined gc_refs value, with clear transitions among gc_refs states. As a result, none of the visit_XYZ traversal callbacks need to check IS_TRACKED() anymore, and those tests were removed. (They were already looking for objects with specific gc_refs states, and the gc_refs state of an untracked object can no longer match any other gc_refs state by accident.) Added more asserts. I expect that the gc_next == NULL indicator for an untracked object is now redundant and can also be removed, but I ran out of time for this.
* OK, I couldn't stand it <0.5 wink>: removed all uncertainty about what'sTim Peters2002-07-011-96/+163
| | | | | | | | | | | | | | | | | | | 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.
* visit_decref(): Two optimizations.Tim Peters2002-06-301-5/+3
| | | | | | | | | | | | | | | | | | | | | | 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.
* SF bug #574132: Major GC related performance regressionTim Peters2002-06-301-13/+43
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | "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>).
* Fix small bug. The count of objects in all generations younger then theNeil Schemenauer2002-06-281-1/+1
| | | | collected one should be zeroed.
* Patch #568124: Add doc string macros.Martin v. Löwis2002-06-131-32/+22
|
* Remove casts to PyObject * when declaration is for PyObject *Jeremy Hylton2002-06-061-3/+3
|
* Add IS_TRACKED and IS_MOVED macros. This makes the logic a little more clear.Neil Schemenauer2002-05-211-7/+10
|
* Move all data for a single generation into a structure. The set ofNeil Schemenauer2002-05-041-73/+97
| | | | | | | | | | | | generations is now an array. This cleans up some code and makes it easy to change the number of generations. Also, implemented a gc_list_is_empty() function. This makes the logic a little clearer in places. The performance impact of these changes should be negligible. One functional change is that allocation/collection counters are always zeroed at the start of a collection. This should fix SF bug #551915. This change is too big for back-porting but the minimal patch on SF looks good for a bugfix release.
* _PyObject_GC_New: Could call PyObject_INIT with a NULL 1st argument.Tim Peters2002-04-281-2/+6
| | | | | | _PyObject_GC_NewVar: Could call PyObject_INIT_VAR likewise. Bugfix candidate.
* Allow PyObject_Del to be used as a function designator. Provide binaryNeil Schemenauer2002-04-121-14/+39
| | | | | | | | compatibility function. Make PyObject_GC_Track and PyObject_GC_UnTrack functions instead of trivial macros wrapping functions. Provide binary compatibility functions.
* Make _PyObject_GC_UnTrack do nothing if WITH_CYCLE_GC is not defined.Neil Schemenauer2002-03-291-0/+2
|
* This is Neil's fix for SF bug 535905 (Evil Trashcan and GC interaction).Guido van Rossum2002-03-281-1/+3
| | | | | | | | The fix makes it possible to call PyObject_GC_UnTrack() more than once on the same object, and then move the PyObject_GC_UnTrack() call to *before* the trashcan code is invoked. BUGFIX CANDIDATE!
* Use pymalloc for realloc() as well.Neil Schemenauer2002-03-221-2/+2
|
* Use pymalloc if it's enabled.Neil Schemenauer2002-03-221-4/+4
|
* Fix spelling mistakes. Bugfix candidates.Neal Norwitz2002-01-291-1/+1
|
* Check for NULL return value of PyList_New (follow-up to patch #486743).Martin v. Löwis2001-12-021-0/+3
|
* Patch #486743: remove bad INCREF, propagate exception in append_objects.Martin v. Löwis2001-12-021-6/+11
|
* Use identity instead of equality when looking for referrers. Fixes #485781.Martin v. Löwis2001-11-291-3/+4
|
* Rename get_referents to get_referrers. Fixes #483815.Martin v. Löwis2001-11-241-12/+12
|
* has_finalizer(): simplified "if (complicated_bool) 1 else 0" toTim Peters2001-11-011-8/+3
| | | | "complicated_bool".