Skip to content

Commit 9cb710d

Browse files
committed
unconditionally align PyInterpreterState
1 parent abb1af7 commit 9cb710d

File tree

3 files changed

+10
-27
lines changed

3 files changed

+10
-27
lines changed

Include/internal/pycore_interp_structs.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,11 @@ struct _Py_unique_id_pool {
748748
The PyInterpreterState typedef is in Include/pytypedefs.h.
749749
*/
750750
struct _is {
751+
/* This structure is carefully allocated so that it's correctly aligned
752+
* to avoid undefined behaviors during LOAD and STORE. The '_malloced'
753+
* field stores the allocated pointer address that will later be freed.
754+
*/
755+
uintptr_t _malloced;
751756

752757
/* This struct contains the eval_breaker,
753758
* which is by far the hottest field in this struct

Include/pyport.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -664,17 +664,14 @@ extern "C" {
664664
#if defined(__has_feature)
665665
# if __has_feature(undefined_behavior_sanitizer)
666666
# define _Py_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize("undefined")))
667-
# define _Py_HAS_UNDEFINED_BEHAVIOR_SANITIZER
668667
# endif
669668
#endif
670669
#if !defined(_Py_NO_SANITIZE_UNDEFINED) && defined(__GNUC__) \
671670
&& ((__GNUC__ >= 5) || (__GNUC__ == 4) && (__GNUC_MINOR__ >= 9))
672671
# define _Py_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize_undefined))
673-
# define _Py_HAS_UNDEFINED_BEHAVIOR_SANITIZER
674672
#endif
675673
#ifndef _Py_NO_SANITIZE_UNDEFINED
676674
# define _Py_NO_SANITIZE_UNDEFINED
677-
# undef _Py_HAS_UNDEFINED_BEHAVIOR_SANITIZER
678675
#endif
679676

680677

Python/pystate.c

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -569,28 +569,19 @@ _PyInterpreterState_Enable(_PyRuntimeState *runtime)
569569
return _PyStatus_OK();
570570
}
571571

572-
#ifdef _Py_HAS_UNDEFINED_BEHAVIOR_SANITIZER
573-
#define RAW_ALIGN_PTR_OFFSET sizeof(void *)
574-
#endif
575-
576572
static PyInterpreterState *
577573
alloc_interpreter(void)
578574
{
579-
#ifdef _Py_HAS_UNDEFINED_BEHAVIOR_SANITIZER
580-
size_t statesize = sizeof(PyInterpreterState);
581575
size_t alignment = _Alignof(PyInterpreterState);
582-
size_t allocsize = statesize + alignment - 1 + RAW_ALIGN_PTR_OFFSET;
576+
size_t allocsize = sizeof(PyInterpreterState) + alignment - 1;
583577
void *mem = PyMem_RawCalloc(1, allocsize);
584578
if (mem == NULL) {
585579
return NULL;
586580
}
587-
char *interp = _Py_ALIGN_UP((char *)mem + RAW_ALIGN_PTR_OFFSET, alignment);
588-
*(void **)(interp - RAW_ALIGN_PTR_OFFSET) = mem;
581+
PyInterpreterState *interp = _Py_ALIGN_UP(mem, alignment);
589582
assert(_Py_IS_ALIGNED(interp, alignment));
590-
return (PyInterpreterState *)interp;
591-
#else
592-
return PyMem_RawCalloc(1, sizeof(PyInterpreterState));
593-
#endif
583+
interp->_malloced = (uintptr_t)mem;
584+
return interp;
594585
}
595586

596587
static void
@@ -604,21 +595,11 @@ free_interpreter(PyInterpreterState *interp)
604595
PyMem_RawFree(interp->obmalloc);
605596
interp->obmalloc = NULL;
606597
}
607-
#ifdef _Py_HAS_UNDEFINED_BEHAVIOR_SANITIZER
608598
assert(_Py_IS_ALIGNED(interp, _Alignof(PyInterpreterState)));
609-
char *mem_location = (char *)interp - RAW_ALIGN_PTR_OFFSET;
610-
void *mem = *((void **)mem_location);
611-
PyMem_RawFree(mem);
612-
#else
613-
PyMem_RawFree(interp);
614-
#endif
599+
PyMem_RawFree((void *)interp->_malloced);
615600
}
616601
}
617602

618-
#ifdef _Py_HAS_UNDEFINED_BEHAVIOR_SANITIZER
619-
#undef RAW_ALIGN_PTR_OFFSET
620-
#endif
621-
622603
#ifndef NDEBUG
623604
static inline int check_interpreter_whence(long);
624605
#endif

0 commit comments

Comments
 (0)