Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions Zend/zend_alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,12 +175,25 @@ static size_t _real_page_size = ZEND_MM_PAGE_SIZE;
typedef uint32_t zend_mm_page_info; /* 4-byte integer */
typedef zend_ulong zend_mm_bitset; /* 4-byte or 8-byte integer */

#define ZEND_MM_ALIGNED_OFFSET(size, alignment) \
(((size_t)(size)) & ((alignment) - 1))
#define ZEND_MM_ALIGNED_BASE(size, alignment) \
(((size_t)(size)) & ~((alignment) - 1))
#define ZEND_MM_SIZE_TO_NUM(size, alignment) \
#ifdef PHP_HAVE_BUILTIN_ALIGN_DOWN
# define ZEND_MM_ALIGNED_BASE(ptr, alignment) \
__builtin_align_down((ptr), (alignment))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about this a bit more, I'm not sure we want the result of ZEND_MM_ALIGNED_BASE to be of the type of ptr, as the base has a different type in every case. I guess we could cast to void* before passing to __builtin_align_down? Then the result is void*, which would force coercion to an appropriate type. WDYT?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there would be benefit in ZEND_MM_ALIGNED_BASE mapping directly to the builtin.

That being said, currently the two implementations return different types (uintptr_t vs T*). I guess it might be more consistent to ensure the result for both is void*.

# define ZEND_MM_ALIGNED_OFFSET(ptr, alignment) \
(((size_t)(ptr)) - (size_t)ZEND_MM_ALIGNED_BASE(ptr, alignment))
#else
# define ZEND_MM_ALIGNED_BASE(ptr, alignment) \
(((uintptr_t)(ptr)) & ~((alignment) - 1))
# define ZEND_MM_ALIGNED_OFFSET(ptr, alignment) \
(((size_t)(ptr)) & ((alignment) - 1))
#endif

#ifdef PHP_HAVE_BUILTIN_ALIGN_UP
# define ZEND_MM_SIZE_TO_NUM(size, alignment) \
(__builtin_align_up((size), (alignment)) / (alignment))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this usage of __builtin_align_up() actually correct when the input is size_t rather than some pointer type?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this one actually only works with size_t (or another integer type) because of the / operator which does not accept a pointer operand. I think this is OK because the macro name explicitly states that it operates on a size, not a pointer.

#else
# define ZEND_MM_SIZE_TO_NUM(size, alignment) \
(((size_t)(size) + ((alignment) - 1)) / (alignment))
#endif

#define ZEND_MM_BITSET_LEN (sizeof(zend_mm_bitset) * 8) /* 32 or 64 */
#define ZEND_MM_PAGE_MAP_LEN (ZEND_MM_PAGES / ZEND_MM_BITSET_LEN) /* 16 or 8 */
Expand Down
2 changes: 2 additions & 0 deletions build/php.m4
Original file line number Diff line number Diff line change
Expand Up @@ -2380,6 +2380,8 @@ AC_CACHE_CHECK([for $1], [php_var],
[__builtin_ssubll_overflow], [long long tmpvar; return $1(3, 7, &tmpvar);],
[__builtin_unreachable], [$1();],
[__builtin_usub_overflow], [unsigned int tmpvar; return $1(3, 7, &tmpvar);],
[__builtin_align_down], [return $1(1, 2) == 0 ? 1 : 0;],
[__builtin_align_up], [return $1(1, 2) == 2 ? 1 : 0;],
[
m4_warn([syntax], [Unsupported builtin '$1', the test may fail.])
$1();
Expand Down
2 changes: 2 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,8 @@ PHP_CHECK_BUILTIN([__builtin_ssubl_overflow])
PHP_CHECK_BUILTIN([__builtin_ssubll_overflow])
PHP_CHECK_BUILTIN([__builtin_unreachable])
PHP_CHECK_BUILTIN([__builtin_usub_overflow])
PHP_CHECK_BUILTIN([__builtin_align_down])
PHP_CHECK_BUILTIN([__builtin_align_up])

dnl Check AVX512
PHP_CHECK_AVX512_SUPPORTS
Expand Down
2 changes: 2 additions & 0 deletions win32/build/config.w32
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,8 @@ if (VS_TOOLSET) {
AC_DEFINE("PHP_HAVE_BUILTIN_SSUBLL_OVERFLOW", 1, "Define to 1 if the compiler supports '__builtin_ssubll_overflow'.");
AC_DEFINE("PHP_HAVE_BUILTIN_SMULL_OVERFLOW", 1, "Define to 1 if the compiler supports '__builtin_smull_overflow '.");
AC_DEFINE("PHP_HAVE_BUILTIN_SMULLL_OVERFLOW", 1, "Define to 1 if the compiler supports '__builtin_smulll_overflow'.");
AC_DEFINE("PHP_HAVE_BUILTIN_ALIGN_DOWN", 1, "Define to 1 if the compiler supports '__builtin_align_down'.");
AC_DEFINE("PHP_HAVE_BUILTIN_ALIGN_UP", 1, "Define to 1 if the compiler supports '__builtin_align_up'.");

if (PHP_SANITIZER == "yes") {
if (COMPILER_NUMERIC_VERSION < 500) {
Expand Down
Loading