Skip to content

Commit 307ba6c

Browse files
committed
Merge branch 'main' into refactor-optimize-structs
2 parents 85da4d5 + b5558cd commit 307ba6c

40 files changed

+494
-456
lines changed

Include/internal/pycore_dict.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -347,8 +347,7 @@ PyDictObject *_PyObject_MaterializeManagedDict_LockHeld(PyObject *);
347347
static inline Py_ssize_t
348348
_PyDict_UniqueId(PyDictObject *mp)
349349
{
350-
// Offset by one so that _ma_watcher_tag=0 represents an unassigned id
351-
return (Py_ssize_t)(mp->_ma_watcher_tag >> DICT_UNIQUE_ID_SHIFT) - 1;
350+
return (Py_ssize_t)(mp->_ma_watcher_tag >> DICT_UNIQUE_ID_SHIFT);
352351
}
353352

354353
static inline void

Include/internal/pycore_object.h

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -336,20 +336,20 @@ _Py_THREAD_INCREF_OBJECT(PyObject *obj, Py_ssize_t unique_id)
336336
{
337337
_PyThreadStateImpl *tstate = (_PyThreadStateImpl *)_PyThreadState_GET();
338338

339-
// Unsigned comparison so that `unique_id=-1`, which indicates that
340-
// per-thread refcounting has been disabled on this object, is handled by
341-
// the "else".
342-
if ((size_t)unique_id < (size_t)tstate->refcounts.size) {
339+
// The table index is `unique_id - 1` because 0 is not a valid unique id.
340+
// Unsigned comparison so that `idx=-1` is handled by the "else".
341+
size_t idx = (size_t)(unique_id - 1);
342+
if (idx < (size_t)tstate->refcounts.size) {
343343
# ifdef Py_REF_DEBUG
344344
_Py_INCREF_IncRefTotal();
345345
# endif
346346
_Py_INCREF_STAT_INC();
347-
tstate->refcounts.values[unique_id]++;
347+
tstate->refcounts.values[idx]++;
348348
}
349349
else {
350350
// The slow path resizes the per-thread refcount array if necessary.
351-
// It handles the unique_id=-1 case to keep the inlinable function smaller.
352-
_PyObject_ThreadIncrefSlow(obj, unique_id);
351+
// It handles the unique_id=0 case to keep the inlinable function smaller.
352+
_PyObject_ThreadIncrefSlow(obj, idx);
353353
}
354354
}
355355

@@ -386,15 +386,15 @@ _Py_THREAD_DECREF_OBJECT(PyObject *obj, Py_ssize_t unique_id)
386386
{
387387
_PyThreadStateImpl *tstate = (_PyThreadStateImpl *)_PyThreadState_GET();
388388

389-
// Unsigned comparison so that `unique_id=-1`, which indicates that
390-
// per-thread refcounting has been disabled on this object, is handled by
391-
// the "else".
392-
if ((size_t)unique_id < (size_t)tstate->refcounts.size) {
389+
// The table index is `unique_id - 1` because 0 is not a valid unique id.
390+
// Unsigned comparison so that `idx=-1` is handled by the "else".
391+
size_t idx = (size_t)(unique_id - 1);
392+
if (idx < (size_t)tstate->refcounts.size) {
393393
# ifdef Py_REF_DEBUG
394394
_Py_DECREF_DecRefTotal();
395395
# endif
396396
_Py_DECREF_STAT_INC();
397-
tstate->refcounts.values[unique_id]--;
397+
tstate->refcounts.values[idx]--;
398398
}
399399
else {
400400
// Directly decref the object if the id is not assigned or if

Include/internal/pycore_optimizer.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,6 @@ struct _PyOptimizerObject {
9898
};
9999

100100
/** Test support **/
101-
typedef struct {
102-
_PyOptimizerObject base;
103-
int64_t count;
104-
} _PyCounterOptimizerObject;
105-
106101
_PyOptimizerObject *_Py_SetOptimizer(PyInterpreterState *interp, _PyOptimizerObject* optimizer);
107102

108103

@@ -119,7 +114,6 @@ PyAPI_FUNC(void) _Py_Executor_DependsOn(_PyExecutorObject *executor, void *obj);
119114
// Export for '_testinternalcapi' shared extension.
120115
PyAPI_FUNC(_PyOptimizerObject *) _Py_GetOptimizer(void);
121116
PyAPI_FUNC(int) _Py_SetTier2Optimizer(_PyOptimizerObject* optimizer);
122-
PyAPI_FUNC(PyObject *) _PyOptimizer_NewCounter(void);
123117
PyAPI_FUNC(PyObject *) _PyOptimizer_NewUOpOptimizer(void);
124118

125119
#define _Py_MAX_ALLOWED_BUILTINS_MODIFICATIONS 3
@@ -150,8 +144,6 @@ int _Py_uop_analyze_and_optimize(struct _PyInterpreterFrame *frame,
150144
_PyUOpInstruction *trace, int trace_len, int curr_stackentries,
151145
_PyBloomFilter *dependencies);
152146

153-
extern PyTypeObject _PyCounterExecutor_Type;
154-
extern PyTypeObject _PyCounterOptimizer_Type;
155147
extern PyTypeObject _PyDefaultOptimizer_Type;
156148
extern PyTypeObject _PyUOpExecutor_Type;
157149
extern PyTypeObject _PyUOpOptimizer_Type;

Include/internal/pycore_uniqueid.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ extern "C" {
1616
// Per-thread reference counting is used along with deferred reference
1717
// counting to avoid scaling bottlenecks due to reference count contention.
1818
//
19-
// An id of -1 is used to indicate that an object doesn't use per-thread
19+
// An id of 0 is used to indicate that an object doesn't use per-thread
2020
// refcounting. This value is used when the object is finalized by the GC
2121
// and during interpreter shutdown to allow the object to be
2222
// deallocated promptly when the object's refcount reaches zero.
@@ -45,6 +45,8 @@ struct _Py_unique_id_pool {
4545
Py_ssize_t size;
4646
};
4747

48+
#define _Py_INVALID_UNIQUE_ID 0
49+
4850
// Assigns the next id from the pool of ids.
4951
extern Py_ssize_t _PyObject_AssignUniqueId(PyObject *obj);
5052

@@ -65,7 +67,7 @@ extern void _PyObject_FinalizePerThreadRefcounts(_PyThreadStateImpl *tstate);
6567
extern void _PyObject_FinalizeUniqueIdPool(PyInterpreterState *interp);
6668

6769
// Increfs the object, resizing the thread-local refcount array if necessary.
68-
PyAPI_FUNC(void) _PyObject_ThreadIncrefSlow(PyObject *obj, Py_ssize_t unique_id);
70+
PyAPI_FUNC(void) _PyObject_ThreadIncrefSlow(PyObject *obj, size_t idx);
6971

7072
#endif /* Py_GIL_DISABLED */
7173

Include/internal/pycore_uop_ids.h

Lines changed: 92 additions & 93 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_uop_metadata.h

Lines changed: 0 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

InternalDocs/generators.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ execution state.
1111

1212
A generator object resumes execution in its frame when its `send()`
1313
method is called. This is analogous to a function executing in its own
14-
fram when it is called, but a function returns to the calling frame only once,
14+
frame when it is called, but a function returns to the calling frame only once,
1515
while a generator "returns" execution to the caller's frame every time
1616
it emits a new item with a
1717
[`yield` expression](https://docs.python.org/dev/reference/expressions.html#yield-expressions).

0 commit comments

Comments
 (0)