bpo-35081: Make some _PyGC macros internal (GH-10507) · python/cpython@1a6be91 (original) (raw)

`@@ -256,18 +256,18 @@ PyAPI_FUNC(Py_ssize_t) _PyGC_CollectIfEnabled(void);

`

256

256

`/* Test if a type has a GC head */

`

257

257

`#define PyType_IS_GC(t) PyType_HasFeature((t), Py_TPFLAGS_HAVE_GC)

`

258

258

``

259

``

`-

/* Test if an object has a GC head */

`

260

``

`-

#ifndef Py_LIMITED_API

`

261

``

`-

#define PyObject_IS_GC(o) (PyType_IS_GC(Py_TYPE(o)) && \

`

262

``

`-

(Py_TYPE(o)->tp_is_gc == NULL || Py_TYPE(o)->tp_is_gc(o)))

`

263

``

`-

#endif

`

264

``

-

265

259

`PyAPI_FUNC(PyVarObject *) _PyObject_GC_Resize(PyVarObject *, Py_ssize_t);

`

266

260

`#define PyObject_GC_Resize(type, op, n) \

`

267

261

` ( (type *) _PyObject_GC_Resize((PyVarObject *)(op), (n)) )

`

268

262

``

269

``

`-

/* GC information is stored BEFORE the object structure. */

`

``

263

+

270

264

`#ifndef Py_LIMITED_API

`

``

265

`+

/* Test if an object has a GC head */

`

``

266

`+

#define PyObject_IS_GC(o) \

`

``

267

`+

(PyType_IS_GC(Py_TYPE(o)) \

`

``

268

`+

&& (Py_TYPE(o)->tp_is_gc == NULL || Py_TYPE(o)->tp_is_gc(o)))

`

``

269

+

``

270

`+

/* GC information is stored BEFORE the object structure. */

`

271

271

`typedef struct {

`

272

272

`// Pointer to next object in the list.

`

273

273

`// 0 means the object is not tracked

`

`@@ -278,10 +278,21 @@ typedef struct {

`

278

278

`uintptr_t _gc_prev;

`

279

279

`} PyGC_Head;

`

280

280

``

281

``

`-

extern PyGC_Head *_PyGC_generation0;

`

282

``

-

283

281

`#define _Py_AS_GC(o) ((PyGC_Head *)(o)-1)

`

284

282

``

``

283

`+

/* True if the object is currently tracked by the GC. */

`

``

284

`+

#define _PyObject_GC_IS_TRACKED(o) (_Py_AS_GC(o)->_gc_next != 0)

`

``

285

+

``

286

`+

/* True if the object may be tracked by the GC in the future, or already is.

`

``

287

`+

This can be useful to implement some optimizations. */

`

``

288

`+

#define _PyObject_GC_MAY_BE_TRACKED(obj) \

`

``

289

`+

(PyObject_IS_GC(obj) && \

`

``

290

`+

(!PyTuple_CheckExact(obj) || _PyObject_GC_IS_TRACKED(obj)))

`

``

291

`+

#endif

`

``

292

+

``

293

+

``

294

`+

#if defined(Py_BUILD_CORE) || defined(Py_BUILD_CORE_BUILTIN)

`

``

295

+

285

296

`/* Bit flags for _gc_prev */

`

286

297

`/* Bit 0 is set when tp_finalize is called */

`

287

298

`#define _PyGC_PREV_MASK_FINALIZED (1)

`

`@@ -304,38 +315,46 @@ extern PyGC_Head *_PyGC_generation0;

`

304

315

` | ((uintptr_t)(p)); \

`

305

316

` } while (0)

`

306

317

``

307

``

`-

#define _PyGCHead_FINALIZED(g) (((g)->_gc_prev & _PyGC_PREV_MASK_FINALIZED) != 0)

`

308

``

`-

#define _PyGCHead_SET_FINALIZED(g) ((g)->_gc_prev |= _PyGC_PREV_MASK_FINALIZED)

`

``

318

`+

#define _PyGCHead_FINALIZED(g) \

`

``

319

`+

(((g)->_gc_prev & _PyGC_PREV_MASK_FINALIZED) != 0)

`

``

320

`+

#define _PyGCHead_SET_FINALIZED(g) \

`

``

321

`+

((g)->_gc_prev |= _PyGC_PREV_MASK_FINALIZED)

`

309

322

``

310

``

`-

#define _PyGC_FINALIZED(o) _PyGCHead_FINALIZED(_Py_AS_GC(o))

`

311

``

`-

#define _PyGC_SET_FINALIZED(o) _PyGCHead_SET_FINALIZED(_Py_AS_GC(o))

`

``

323

`+

#define _PyGC_FINALIZED(o) \

`

``

324

`+

_PyGCHead_FINALIZED(_Py_AS_GC(o))

`

``

325

`+

#define _PyGC_SET_FINALIZED(o) \

`

``

326

`+

_PyGCHead_SET_FINALIZED(_Py_AS_GC(o))

`

312

327

``

313

328

`/* Tell the GC to track this object.

`

314

329

` *

`

315

330

` * NB: While the object is tracked by the collector, it must be safe to call the

`

316

331

` * ob_traverse method.

`

317

332

` *

`

318

``

`-

`

``

333

`+

`

319

334

` * because it's not object header. So we don't use _PyGCHead_PREV() and

`

320

335

` * _PyGCHead_SET_PREV() for it to avoid unnecessary bitwise operations.

`

``

336

`+

`

``

337

`+

`

321

338

` */

`

322

339

`#define _PyObject_GC_TRACK(o) do { \

`

323

340

` PyGC_Head *g = _Py_AS_GC(o); \

`

324

341

` if (g->_gc_next != 0) { \

`

325

342

` Py_FatalError("GC object already tracked"); \

`

326

343

` } \

`

327

344

` assert((g->_gc_prev & _PyGC_PREV_MASK_COLLECTING) == 0); \

`

328

``

`-

PyGC_Head last = (PyGC_Head)(_PyGC_generation0->_gc_prev); \

`

``

345

`+

PyGC_Head last = (PyGC_Head)(_PyRuntime.gc.generation0->_gc_prev); \

`

329

346

` _PyGCHead_SET_NEXT(last, g); \

`

330

347

` _PyGCHead_SET_PREV(g, last); \

`

331

``

`-

_PyGCHead_SET_NEXT(g, _PyGC_generation0); \

`

332

``

`-

_PyGC_generation0->_gc_prev = (uintptr_t)g; \

`

``

348

`+

_PyGCHead_SET_NEXT(g, _PyRuntime.gc.generation0); \

`

``

349

`+

_PyRuntime.gc.generation0->_gc_prev = (uintptr_t)g; \

`

333

350

` } while (0);

`

334

351

``

335

352

`/* Tell the GC to stop tracking this object.

`

336

353

` *

`

337

354

` * Internal note: This may be called while GC. So _PyGC_PREV_MASK_COLLECTING must

`

338

355

` * be cleared. But _PyGC_PREV_MASK_FINALIZED bit is kept.

`

``

356

`+

`

``

357

`+

`

339

358

` */

`

340

359

`#define _PyObject_GC_UNTRACK(o) do { \

`

341

360

` PyGC_Head *g = _Py_AS_GC(o); \

`

`@@ -347,25 +366,25 @@ extern PyGC_Head *_PyGC_generation0;

`

347

366

` g->_gc_next = 0; \

`

348

367

` g->_gc_prev &= _PyGC_PREV_MASK_FINALIZED; \

`

349

368

` } while (0);

`

350

``

-

351

``

`-

/* True if the object is currently tracked by the GC. */

`

352

``

`-

#define _PyObject_GC_IS_TRACKED(o) (_Py_AS_GC(o)->_gc_next != 0)

`

353

``

-

354

``

`-

/* True if the object may be tracked by the GC in the future, or already is.

`

355

``

`-

This can be useful to implement some optimizations. */

`

356

``

`-

#define _PyObject_GC_MAY_BE_TRACKED(obj) \

`

357

``

`-

(PyObject_IS_GC(obj) && \

`

358

``

`-

(!PyTuple_CheckExact(obj) || _PyObject_GC_IS_TRACKED(obj)))

`

359

``

`-

#endif /* Py_LIMITED_API */

`

``

369

`+

#endif /* defined(Py_BUILD_CORE) || defined(Py_BUILD_CORE_BUILTIN) */

`

360

370

``

361

371

`#ifndef Py_LIMITED_API

`

362

372

`PyAPI_FUNC(PyObject *) _PyObject_GC_Malloc(size_t size);

`

363

373

`PyAPI_FUNC(PyObject *) _PyObject_GC_Calloc(size_t size);

`

364

374

`#endif /* !Py_LIMITED_API */

`

365

375

`PyAPI_FUNC(PyObject *) _PyObject_GC_New(PyTypeObject *);

`

366

376

`PyAPI_FUNC(PyVarObject *) _PyObject_GC_NewVar(PyTypeObject *, Py_ssize_t);

`

``

377

+

``

378

`+

/* Tell the GC to track this object.

`

``

379

`+

`

``

380

`+

`

367

381

`PyAPI_FUNC(void) PyObject_GC_Track(void *);

`

``

382

+

``

383

`+

/* Tell the GC to stop tracking this object.

`

``

384

`+

`

``

385

`+

`

368

386

`PyAPI_FUNC(void) PyObject_GC_UnTrack(void *);

`

``

387

+

369

388

`PyAPI_FUNC(void) PyObject_GC_Del(void *);

`

370

389

``

371

390

`#define PyObject_GC_New(type, typeobj) \

`