| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -317,7 +317,7 @@ _PyLong_FlipSign(PyLongObject *op) { | |||
| 317 | 317 | ||
| 318 | 318 | #define _PyLong_DIGIT_INIT(val) \ | |
| 319 | 319 | { \ | |
| 320 | - .ob_base = _PyObject_HEAD_INIT(&PyLong_Type) \ | ||
| 320 | + .ob_base = _PyObject_HEAD_INIT(&PyLong_Type), \ | ||
| 321 | 321 | .long_value = { \ | |
| 322 | 322 | .lv_tag = TAG_FROM_SIGN_AND_SIZE( \ | |
| 323 | 323 | (val) == 0 ? 0 : ((val) < 0 ? -1 : 1), \ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -54,16 +54,24 @@ PyAPI_FUNC(int) _PyObject_IsFreed(PyObject *); | |||
| 54 | 54 | Furthermore, we can't use designated initializers in Extensions since these | |
| 55 | 55 | are not supported pre-C++20. Thus, keeping an internal copy here is the most | |
| 56 | 56 | backwards compatible solution */ | |
| 57 | + #if defined(Py_NOGIL) | ||
| 58 | + #define _PyObject_HEAD_INIT(type) \ | ||
| 59 | + { \ | ||
| 60 | + .ob_ref_local = _Py_IMMORTAL_REFCNT_LOCAL, \ | ||
| 61 | + .ob_type = (type) \ | ||
| 62 | + } | ||
| 63 | + #else | ||
| 57 | 64 | #define _PyObject_HEAD_INIT(type) \ | |
| 58 | 65 | { \ | |
| 59 | 66 | .ob_refcnt = _Py_IMMORTAL_REFCNT, \ | |
| 60 | 67 | .ob_type = (type) \ | |
| 61 | - }, | ||
| 68 | + } | ||
| 69 | + #endif | ||
| 62 | 70 | #define _PyVarObject_HEAD_INIT(type, size) \ | |
| 63 | 71 | { \ | |
| 64 | - .ob_base = _PyObject_HEAD_INIT(type) \ | ||
| 72 | + .ob_base = _PyObject_HEAD_INIT(type), \ | ||
| 65 | 73 | .ob_size = size \ | |
| 66 | - }, | ||
| 74 | + } | ||
| 67 | 75 | ||
| 68 | 76 | extern void _Py_NO_RETURN _Py_FatalRefcountErrorFunc( | |
| 69 | 77 | const char *func, | |
@@ -95,24 +103,63 @@ static inline void _Py_RefcntAdd(PyObject* op, Py_ssize_t n) | |||
| 95 | 103 | #ifdef Py_REF_DEBUG | |
| 96 | 104 | _Py_AddRefTotal(_PyInterpreterState_GET(), n); | |
| 97 | 105 | #endif | |
| 106 | + #if !defined(Py_NOGIL) | ||
| 98 | 107 | op->ob_refcnt += n; | |
| 108 | + #else | ||
| 109 | + if (_Py_IsOwnedByCurrentThread(op)) { | ||
| 110 | + uint32_t local = op->ob_ref_local; | ||
| 111 | + Py_ssize_t refcnt = (Py_ssize_t)local + n; | ||
| 112 | + # if PY_SSIZE_T_MAX > UINT32_MAX | ||
| 113 | + if (refcnt > (Py_ssize_t)UINT32_MAX) { | ||
| 114 | + // Make the object immortal if the 32-bit local reference count | ||
| 115 | + // would overflow. | ||
| 116 | + refcnt = _Py_IMMORTAL_REFCNT_LOCAL; | ||
| 117 | + } | ||
| 118 | + # endif | ||
| 119 | + _Py_atomic_store_uint32_relaxed(&op->ob_ref_local, (uint32_t)refcnt); | ||
| 120 | + } | ||
| 121 | + else { | ||
| 122 | + _Py_atomic_add_ssize(&op->ob_ref_shared, (n << _Py_REF_SHARED_SHIFT)); | ||
| 123 | + } | ||
| 124 | + #endif | ||
| 99 | 125 | } | |
| 100 | 126 | #define _Py_RefcntAdd(op, n) _Py_RefcntAdd(_PyObject_CAST(op), n) | |
| 101 | 127 | ||
| 102 | 128 | static inline void _Py_SetImmortal(PyObject *op) | |
| 103 | 129 | { | |
| 104 | 130 | if (op) { | |
| 131 | + #ifdef Py_NOGIL | ||
| 132 | + op->ob_tid = _Py_UNOWNED_TID; | ||
| 133 | + op->ob_ref_local = _Py_IMMORTAL_REFCNT_LOCAL; | ||
| 134 | + op->ob_ref_shared = 0; | ||
| 135 | + #else | ||
| 105 | 136 | op->ob_refcnt = _Py_IMMORTAL_REFCNT; | |
| 137 | + #endif | ||
| 106 | 138 | } | |
| 107 | 139 | } | |
| 108 | 140 | #define _Py_SetImmortal(op) _Py_SetImmortal(_PyObject_CAST(op)) | |
| 109 | 141 | ||
| 142 | + // Makes an immortal object mortal again with the specified refcnt. Should only | ||
| 143 | + // be used during runtime finalization. | ||
| 144 | + static inline void _Py_SetMortal(PyObject *op, Py_ssize_t refcnt) | ||
| 145 | + { | ||
| 146 | + if (op) { | ||
| 147 | + assert(_Py_IsImmortal(op)); | ||
| 148 | + #ifdef Py_NOGIL | ||
| 149 | + op->ob_tid = _Py_UNOWNED_TID; | ||
| 150 | + op->ob_ref_local = 0; | ||
| 151 | + op->ob_ref_shared = _Py_REF_SHARED(refcnt, _Py_REF_MERGED); | ||
| 152 | + #else | ||
| 153 | + op->ob_refcnt = refcnt; | ||
| 154 | + #endif | ||
| 155 | + } | ||
| 156 | + } | ||
| 157 | + | ||
| 110 | 158 | /* _Py_ClearImmortal() should only be used during runtime finalization. */ | |
| 111 | 159 | static inline void _Py_ClearImmortal(PyObject *op) | |
| 112 | 160 | { | |
| 113 | 161 | if (op) { | |
| 114 | - assert(op->ob_refcnt == _Py_IMMORTAL_REFCNT); | ||
| 115 | - op->ob_refcnt = 1; | ||
| 162 | + _Py_SetMortal(op, 1); | ||
| 116 | 163 | Py_DECREF(op); | |
| 117 | 164 | } | |
| 118 | 165 | } | |
@@ -122,6 +169,7 @@ static inline void _Py_ClearImmortal(PyObject *op) | |||
| 122 | 169 | op = NULL; \ | |
| 123 | 170 | } while (0) | |
| 124 | 171 | ||
| 172 | + #if !defined(Py_NOGIL) | ||
| 125 | 173 | static inline void | |
| 126 | 174 | _Py_DECREF_SPECIALIZED(PyObject *op, const destructor destruct) | |
| 127 | 175 | { | |
@@ -161,6 +209,37 @@ _Py_DECREF_NO_DEALLOC(PyObject *op) | |||
| 161 | 209 | #endif | |
| 162 | 210 | } | |
| 163 | 211 | ||
| 212 | + #else | ||
| 213 | + // TODO: implement Py_DECREF specializations for Py_NOGIL build | ||
| 214 | + static inline void | ||
| 215 | + _Py_DECREF_SPECIALIZED(PyObject *op, const destructor destruct) | ||
| 216 | + { | ||
| 217 | + Py_DECREF(op); | ||
| 218 | + } | ||
| 219 | + | ||
| 220 | + static inline void | ||
| 221 | + _Py_DECREF_NO_DEALLOC(PyObject *op) | ||
| 222 | + { | ||
| 223 | + Py_DECREF(op); | ||
| 224 | + } | ||
| 225 | + | ||
| 226 | + static inline int | ||
| 227 | + _Py_REF_IS_MERGED(Py_ssize_t ob_ref_shared) | ||
| 228 | + { | ||
| 229 | + return (ob_ref_shared & _Py_REF_SHARED_FLAG_MASK) == _Py_REF_MERGED; | ||
| 230 | + } | ||
| 231 | + | ||
| 232 | + static inline int | ||
| 233 | + _Py_REF_IS_QUEUED(Py_ssize_t ob_ref_shared) | ||
| 234 | + { | ||
| 235 | + return (ob_ref_shared & _Py_REF_SHARED_FLAG_MASK) == _Py_REF_QUEUED; | ||
| 236 | + } | ||
| 237 | + | ||
| 238 | + // Merge the local and shared reference count fields and add `extra` to the | ||
| 239 | + // refcount when merging. | ||
| 240 | + Py_ssize_t _Py_ExplicitMergeRefcount(PyObject *op, Py_ssize_t extra); | ||
| 241 | + #endif // !defined(Py_NOGIL) | ||
| 242 | + | ||
| 164 | 243 | #ifdef Py_REF_DEBUG | |
| 165 | 244 | # undef _Py_DEC_REFTOTAL | |
| 166 | 245 | #endif | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -129,13 +129,13 @@ extern PyTypeObject _PyExc_MemoryError; | |||
| 129 | 129 | .latin1 = _Py_str_latin1_INIT, \ | |
| 130 | 130 | }, \ | |
| 131 | 131 | .tuple_empty = { \ | |
| 132 | - .ob_base = _PyVarObject_HEAD_INIT(&PyTuple_Type, 0) \ | ||
| 132 | + .ob_base = _PyVarObject_HEAD_INIT(&PyTuple_Type, 0), \ | ||
| 133 | 133 | }, \ | |
| 134 | 134 | .hamt_bitmap_node_empty = { \ | |
| 135 | - .ob_base = _PyVarObject_HEAD_INIT(&_PyHamt_BitmapNode_Type, 0) \ | ||
| 135 | + .ob_base = _PyVarObject_HEAD_INIT(&_PyHamt_BitmapNode_Type, 0), \ | ||
| 136 | 136 | }, \ | |
| 137 | 137 | .context_token_missing = { \ | |
| 138 | - .ob_base = _PyObject_HEAD_INIT(&_PyContextTokenMissing_Type) \ | ||
| 138 | + .ob_base = _PyObject_HEAD_INIT(&_PyContextTokenMissing_Type), \ | ||
| 139 | 139 | }, \ | |
| 140 | 140 | }, \ | |
| 141 | 141 | }, \ | |
@@ -172,11 +172,11 @@ extern PyTypeObject _PyExc_MemoryError; | |||
| 172 | 172 | .singletons = { \ | |
| 173 | 173 | ._not_used = 1, \ | |
| 174 | 174 | .hamt_empty = { \ | |
| 175 | - .ob_base = _PyObject_HEAD_INIT(&_PyHamt_Type) \ | ||
| 175 | + .ob_base = _PyObject_HEAD_INIT(&_PyHamt_Type), \ | ||
| 176 | 176 | .h_root = (PyHamtNode*)&_Py_SINGLETON(hamt_bitmap_node_empty), \ | |
| 177 | 177 | }, \ | |
| 178 | 178 | .last_resort_memory_error = { \ | |
| 179 | - _PyObject_HEAD_INIT(&_PyExc_MemoryError) \ | ||
| 179 | + _PyObject_HEAD_INIT(&_PyExc_MemoryError), \ | ||
| 180 | 180 | .args = (PyObject*)&_Py_SINGLETON(tuple_empty) \ | |
| 181 | 181 | }, \ | |
| 182 | 182 | }, \ | |
@@ -206,7 +206,7 @@ extern PyTypeObject _PyExc_MemoryError; | |||
| 206 | 206 | ||
| 207 | 207 | #define _PyBytes_SIMPLE_INIT(CH, LEN) \ | |
| 208 | 208 | { \ | |
| 209 | - _PyVarObject_HEAD_INIT(&PyBytes_Type, (LEN)) \ | ||
| 209 | + _PyVarObject_HEAD_INIT(&PyBytes_Type, (LEN)), \ | ||
| 210 | 210 | .ob_shash = -1, \ | |
| 211 | 211 | .ob_sval = { (CH) }, \ | |
| 212 | 212 | } | |
@@ -217,7 +217,7 @@ extern PyTypeObject _PyExc_MemoryError; | |||
| 217 | 217 | ||
| 218 | 218 | #define _PyUnicode_ASCII_BASE_INIT(LITERAL, ASCII) \ | |
| 219 | 219 | { \ | |
| 220 | - .ob_base = _PyObject_HEAD_INIT(&PyUnicode_Type) \ | ||
| 220 | + .ob_base = _PyObject_HEAD_INIT(&PyUnicode_Type), \ | ||
| 221 | 221 | .length = sizeof(LITERAL) - 1, \ | |
| 222 | 222 | .hash = -1, \ | |
| 223 | 223 | .state = { \ | |
| Back | FazBrowse Home | New Git URL |
0 commit comments