Commit 7b9d54ee95f for php

commit 7b9d54ee95faea25c83c62591be2bf3e2fb57dda
Author: Marc <m@pyc.ac>
Date:   Sun Nov 8 20:26:35 2026 +0700

    perf: avoid stack accessor calls for output buffering (#25300)

    * avoid stack accessor calls for output buffering

    * move to header with zend_always_inline instead

    * move macro definition

    * move other small functions too

diff --git a/Zend/zend_stack.c b/Zend/zend_stack.c
index d999d684d05..0d9e11d9824 100644
--- a/Zend/zend_stack.c
+++ b/Zend/zend_stack.c
@@ -19,8 +19,6 @@
 #include "zend.h"
 #include "zend_stack.h"

-#define ZEND_STACK_ELEMENT(stack, n) ((void *)((char *) (stack)->elements + (stack)->size * (n)))
-
 ZEND_API void zend_stack_init(zend_stack *stack, int size)
 {
 	stack->size = size;
@@ -41,22 +39,6 @@ ZEND_API int zend_stack_push(zend_stack *stack, const void *element)
 }


-ZEND_API void *zend_stack_top(const zend_stack *stack)
-{
-	if (stack->top > 0) {
-		return ZEND_STACK_ELEMENT(stack, stack->top - 1);
-	} else {
-		return NULL;
-	}
-}
-
-
-ZEND_API void zend_stack_del_top(zend_stack *stack)
-{
-	--stack->top;
-}
-
-
 ZEND_API int zend_stack_int_top(const zend_stack *stack)
 {
 	int *e = zend_stack_top(stack);
@@ -68,12 +50,6 @@ ZEND_API int zend_stack_int_top(const zend_stack *stack)
 }


-ZEND_API bool zend_stack_is_empty(const zend_stack *stack)
-{
-	return stack->top == 0;
-}
-
-
 ZEND_API void zend_stack_destroy(zend_stack *stack)
 {
 	if (stack->elements) {
@@ -83,18 +59,6 @@ ZEND_API void zend_stack_destroy(zend_stack *stack)
 }


-ZEND_API void *zend_stack_base(const zend_stack *stack)
-{
-	return stack->elements;
-}
-
-
-ZEND_API int zend_stack_count(const zend_stack *stack)
-{
-	return stack->top;
-}
-
-
 ZEND_API void zend_stack_apply(zend_stack *stack, int type, int (*apply_function)(void *element))
 {
 	int i;
diff --git a/Zend/zend_stack.h b/Zend/zend_stack.h
index 66c90f0b521..7006145ed80 100644
--- a/Zend/zend_stack.h
+++ b/Zend/zend_stack.h
@@ -28,6 +28,7 @@ typedef struct _zend_stack {


 #define STACK_BLOCK_SIZE 16
+#define ZEND_STACK_ELEMENT(stack, n) ((void *)((char *) (stack)->elements + (stack)->size * (n)))

 typedef enum {
 	ZEND_STACK_APPLY_TOPDOWN,
@@ -37,16 +38,40 @@ typedef enum {
 BEGIN_EXTERN_C()
 ZEND_API void zend_stack_init(zend_stack *stack, int size);
 ZEND_API int zend_stack_push(zend_stack *stack, const void *element);
-ZEND_API void *zend_stack_top(const zend_stack *stack);
-ZEND_API void zend_stack_del_top(zend_stack *stack);
 ZEND_API int zend_stack_int_top(const zend_stack *stack);
-ZEND_API bool zend_stack_is_empty(const zend_stack *stack);
 ZEND_API void zend_stack_destroy(zend_stack *stack);
-ZEND_API void *zend_stack_base(const zend_stack *stack);
-ZEND_API int zend_stack_count(const zend_stack *stack);
 ZEND_API void zend_stack_apply(zend_stack *stack, int type, int (*apply_function)(void *element));
 ZEND_API void zend_stack_apply_with_argument(zend_stack *stack, zend_stack_apply_direction type, int (*apply_function)(void *element, void *arg), void *arg);
 ZEND_API void zend_stack_clean(zend_stack *stack, void (*func)(void *), bool free_elements);
 END_EXTERN_C()

+static zend_always_inline void *zend_stack_top(const zend_stack *stack)
+{
+	if (stack->top > 0) {
+		return ZEND_STACK_ELEMENT(stack, stack->top - 1);
+	} else {
+		return NULL;
+	}
+}
+
+static zend_always_inline void zend_stack_del_top(zend_stack *stack)
+{
+	--stack->top;
+}
+
+static zend_always_inline bool zend_stack_is_empty(const zend_stack *stack)
+{
+	return stack->top == 0;
+}
+
+static zend_always_inline void *zend_stack_base(const zend_stack *stack)
+{
+	return stack->elements;
+}
+
+static zend_always_inline int zend_stack_count(const zend_stack *stack)
+{
+	return stack->top;
+}
+
 #endif /* ZEND_STACK_H */
diff --git a/main/output.c b/main/output.c
index f7e1244a3d9..d56f04e0dae 100644
--- a/main/output.c
+++ b/main/output.c
@@ -1111,7 +1111,7 @@ static inline void php_output_op(int op, const char *str, size_t len)

 		if (obh_cnt > 1) {
 			zend_stack_apply_with_argument(&OG(handlers), ZEND_STACK_APPLY_TOPDOWN, php_output_stack_apply_op, &context);
-		} else if ((active = zend_stack_top(&OG(handlers))) && (!((*active)->flags & PHP_OUTPUT_HANDLER_DISABLED))) {
+		} else if ((active = zend_stack_base(&OG(handlers))) && (!((*active)->flags & PHP_OUTPUT_HANDLER_DISABLED))) {
 			php_output_handler_op(*active, &context);
 		} else {
 			php_output_context_pass(&context);