Skip to content

Commit 62875c8

Browse files
committed
Use flags for speed. Still not working
1 parent 2769005 commit 62875c8

22 files changed

+67
-43
lines changed

Include/internal/pycore_freelist.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ _Py_freelists_GET(void)
3838
_PyFreeList_Push(&_Py_freelists_GET()->NAME, _PyObject_CAST(op), limit)
3939

4040
// Pops a PyObject from the freelist, returns NULL if the freelist is empty.
41-
#define _Py_FREELIST_POP(TYPE, NAME) \
42-
_Py_CAST(TYPE*, _PyFreeList_Pop(&_Py_freelists_GET()->NAME))
41+
#define _Py_FREELIST_POP(TYPE, NAME, IS_GC) \
42+
_Py_CAST(TYPE*, _PyFreeList_Pop(&_Py_freelists_GET()->NAME, (IS_GC) ? _Py_GC_OBJECT : 0))
4343

4444
// Pops a non-PyObject data structure from the freelist, returns NULL if the
4545
// freelist is empty.
@@ -83,12 +83,13 @@ _PyFreeList_PopNoStats(struct _Py_freelist *fl)
8383
}
8484

8585
static inline PyObject *
86-
_PyFreeList_Pop(struct _Py_freelist *fl)
86+
_PyFreeList_Pop(struct _Py_freelist *fl, int flags)
8787
{
8888
PyObject *op = _PyFreeList_PopNoStats(fl);
8989
if (op != NULL) {
9090
OBJECT_STAT_INC(from_freelist);
9191
_Py_NewReference(op);
92+
op->ob_flags = flags;
9293
}
9394
return op;
9495
}

Include/internal/pycore_gc.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,7 @@ static inline int _PyObject_GC_IS_TRACKED(PyObject *op) {
7474
#ifdef Py_GIL_DISABLED
7575
return _PyObject_HAS_GC_BITS(op, _PyGC_BITS_TRACKED);
7676
#else
77-
PyGC_Head *gc = _Py_AS_GC(op);
78-
return (gc->_gc_next != 0);
77+
return (op->ob_flags & _Py_GC_TRACKED) != 0;
7978
#endif
8079
}
8180
#define _PyObject_GC_IS_TRACKED(op) _PyObject_GC_IS_TRACKED(_Py_CAST(PyObject*, op))
@@ -232,6 +231,8 @@ static inline void _PyObject_GC_TRACK(
232231
gc->_gc_next = ((uintptr_t)live);
233232
live->_gc_prev = (uintptr_t)gc;
234233
assert((gc->_gc_next & 1) == 0);
234+
assert(op->ob_flags & _Py_GC_OBJECT);
235+
op->ob_flags |= _Py_GC_TRACKED;
235236
#endif
236237
}
237238

@@ -266,6 +267,7 @@ static inline void _PyObject_GC_UNTRACK(
266267
_PyGCHead_SET_PREV(next, prev);
267268
gc->_gc_next = 0;
268269
gc->_gc_prev &= _PyGC_PREV_MASK_FINALIZED;
270+
op->ob_flags &= ~_Py_GC_TRACKED;
269271
#endif
270272
}
271273

Include/internal/pycore_object.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ _Py_DECREF_CODE(PyCodeObject *co)
438438

439439
extern void _Py_CandidateCycleRoot(PyObject *op);
440440

441-
static inline void Py_DECREF_MORTAL(const char *filename, int lineno, PyObject *op)
441+
static inline void Py_DecrefMortal(const char *filename, int lineno, PyObject *op)
442442
{
443443
if (op->ob_refcnt <= 0) {
444444
_Py_NegativeRefcount(filename, lineno, op);
@@ -451,11 +451,13 @@ static inline void Py_DECREF_MORTAL(const char *filename, int lineno, PyObject *
451451
if (--op->ob_refcnt == 0) {
452452
_Py_Dealloc(op);
453453
}
454-
else if (PyObject_GC_IsTracked(op)) {
455-
_Py_CandidateCycleRoot(op);
454+
else {
455+
if (PyObject_GC_IsTracked(op)) {
456+
_Py_CandidateCycleRoot(op);
457+
}
456458
}
457459
}
458-
#define Py_DECREF_MORTAL(op) Py_DECREF_MORTAL(__FILE__, __LINE__, _PyObject_CAST(op))
460+
#define Py_DECREF_MORTAL(op) Py_DecrefMortal(__FILE__, __LINE__, _PyObject_CAST(op))
459461

460462
static inline void _Py_DECREF_MORTAL_SPECIALIZED(const char *filename, int lineno, PyObject *op, destructor destruct)
461463
{
@@ -486,6 +488,7 @@ extern Py_NO_INLINE PyAPI_FUNC(void) Py_DECREF_MORTAL(PyObject *op);
486488
static inline void Py_DECREF_MORTAL_SPECIALIZED(PyObject *op, destructor destruct)
487489
{
488490
assert(!_Py_IsStaticImmortal(op));
491+
assert(!PyObject_GC_IsTracked(op));
489492
_Py_DECREF_STAT_INC();
490493
if (--op->ob_refcnt == 0) {
491494
_PyReftracerTrack(op, PyRefTracer_DESTROY);
@@ -852,9 +855,7 @@ _PyObject_GET_WEAKREFS_LISTPTR_FROM_OFFSET(PyObject *op)
852855
static inline int
853856
_PyObject_IS_GC(PyObject *obj)
854857
{
855-
PyTypeObject *type = Py_TYPE(obj);
856-
return (_PyType_IS_GC(type)
857-
&& (type->tp_is_gc == NULL || type->tp_is_gc(obj)));
858+
return (obj->ob_flags & _Py_GC_OBJECT) != 0;
858859
}
859860

860861
// Fast inlined version of PyObject_Hash()

Include/refcount.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ PyAPI_FUNC(void) _Py_DecRef(PyObject *);
246246

247247
static inline Py_ALWAYS_INLINE void Py_INCREF(PyObject *op)
248248
{
249+
assert((op->ob_flags & (_Py_GC_OBJECT | _Py_GC_TRACKED)) != _Py_GC_TRACKED);
249250
#if defined(Py_LIMITED_API) && (Py_LIMITED_API+0 >= 0x030c0000 || defined(Py_REF_DEBUG))
250251
// Stable ABI implements Py_INCREF() as a function call on limited C API
251252
// version 3.12 and newer, and on Python built in debug mode. _Py_IncRef()

Modules/_asynciomodule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2052,7 +2052,7 @@ future_new_iter(PyObject *fut)
20522052
asyncio_state *state = get_asyncio_state_by_def((PyObject *)fut);
20532053
ENSURE_FUTURE_ALIVE(state, fut)
20542054

2055-
it = _Py_FREELIST_POP(futureiterobject, futureiters);
2055+
it = _Py_FREELIST_POP(futureiterobject, futureiters, 1);
20562056
if (it == NULL) {
20572057
it = PyObject_GC_New(futureiterobject, state->FutureIterType);
20582058
if (it == NULL) {

Objects/classobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ PyMethod_New(PyObject *func, PyObject *self)
114114
PyErr_BadInternalCall();
115115
return NULL;
116116
}
117-
PyMethodObject *im = _Py_FREELIST_POP(PyMethodObject, pymethodobjects);
117+
PyMethodObject *im = _Py_FREELIST_POP(PyMethodObject, pymethodobjects, 1);
118118
if (im == NULL) {
119119
im = PyObject_GC_New(PyMethodObject, &PyMethod_Type);
120120
if (im == NULL) {

Objects/complexobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ complex_subtype_from_c_complex(PyTypeObject *type, Py_complex cval)
410410
PyObject *
411411
PyComplex_FromCComplex(Py_complex cval)
412412
{
413-
PyComplexObject *op = _Py_FREELIST_POP(PyComplexObject, complexes);
413+
PyComplexObject *op = _Py_FREELIST_POP(PyComplexObject, complexes, 0);
414414

415415
if (op == NULL) {
416416
/* Inline PyObject_New */

Objects/dictobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -872,7 +872,7 @@ new_dict(PyInterpreterState *interp,
872872
Py_ssize_t used, int free_values_on_failure)
873873
{
874874
assert(keys != NULL);
875-
PyDictObject *mp = _Py_FREELIST_POP(PyDictObject, dicts);
875+
PyDictObject *mp = _Py_FREELIST_POP(PyDictObject, dicts, 1);
876876
if (mp == NULL) {
877877
mp = PyObject_GC_New(PyDictObject, &PyDict_Type);
878878
if (mp == NULL) {

Objects/exceptions.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3978,6 +3978,7 @@ get_memory_error(int allow_allocation, PyObject *args, PyObject *kwds)
39783978
self->dict = NULL;
39793979
self->args = (PyObject *)&_Py_SINGLETON(tuple_empty);
39803980
_Py_NewReference((PyObject *)self);
3981+
((PyObject *)self)->ob_flags = _Py_GC_OBJECT;
39813982
_PyObject_GC_TRACK(self);
39823983
}
39833984
MEMERRORS_UNLOCK(state);

Objects/floatobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ PyFloat_GetInfo(void)
123123
PyObject *
124124
PyFloat_FromDouble(double fval)
125125
{
126-
PyFloatObject *op = _Py_FREELIST_POP(PyFloatObject, floats);
126+
PyFloatObject *op = _Py_FREELIST_POP(PyFloatObject, floats, 0);
127127
if (op == NULL) {
128128
op = PyObject_Malloc(sizeof(PyFloatObject));
129129
if (!op) {

0 commit comments

Comments
 (0)