Skip to content

Remove custom alloca #8513

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
May 27, 2022
Merged
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
19 changes: 9 additions & 10 deletions Zend/Optimizer/dce.c
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@ static inline bool may_throw_dce_exception(const zend_op *opline) {
return opline->opcode == ZEND_ADD_ARRAY_ELEMENT && opline->op2_type == IS_UNUSED;
}

int dce_optimize_op_array(zend_op_array *op_array, zend_ssa *ssa, bool reorder_dtor_effects) {
int dce_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *optimizer_ctx, zend_ssa *ssa, bool reorder_dtor_effects) {
int i;
zend_ssa_phi *phi;
int removed_ops = 0;
Expand All @@ -536,20 +536,17 @@ int dce_optimize_op_array(zend_op_array *op_array, zend_ssa *ssa, bool reorder_d
ctx.op_array = op_array;
ctx.reorder_dtor_effects = reorder_dtor_effects;

void *checkpoint = zend_arena_checkpoint(optimizer_ctx->arena);
/* We have no dedicated phi vector, so we use the whole ssa var vector instead */
ctx.instr_worklist_len = zend_bitset_len(op_array->last);
ctx.instr_worklist = alloca(sizeof(zend_ulong) * ctx.instr_worklist_len);
memset(ctx.instr_worklist, 0, sizeof(zend_ulong) * ctx.instr_worklist_len);
ctx.instr_worklist = zend_arena_calloc(&optimizer_ctx->arena, ctx.instr_worklist_len, sizeof(zend_ulong));
ctx.phi_worklist_len = zend_bitset_len(ssa->vars_count);
ctx.phi_worklist = alloca(sizeof(zend_ulong) * ctx.phi_worklist_len);
memset(ctx.phi_worklist, 0, sizeof(zend_ulong) * ctx.phi_worklist_len);
ctx.phi_worklist_no_val = alloca(sizeof(zend_ulong) * ctx.phi_worklist_len);
memset(ctx.phi_worklist_no_val, 0, sizeof(zend_ulong) * ctx.phi_worklist_len);
ctx.phi_worklist = zend_arena_calloc(&optimizer_ctx->arena, ctx.phi_worklist_len, sizeof(zend_ulong));
ctx.phi_worklist_no_val = zend_arena_calloc(&optimizer_ctx->arena, ctx.phi_worklist_len, sizeof(zend_ulong));

/* Optimistically assume all instructions and phis to be dead */
ctx.instr_dead = alloca(sizeof(zend_ulong) * ctx.instr_worklist_len);
memset(ctx.instr_dead, 0, sizeof(zend_ulong) * ctx.instr_worklist_len);
ctx.phi_dead = alloca(sizeof(zend_ulong) * ctx.phi_worklist_len);
ctx.instr_dead = zend_arena_calloc(&optimizer_ctx->arena, ctx.instr_worklist_len, sizeof(zend_ulong));
ctx.phi_dead = zend_arena_alloc(&optimizer_ctx->arena, ctx.phi_worklist_len * sizeof(zend_ulong));
memset(ctx.phi_dead, 0xff, sizeof(zend_ulong) * ctx.phi_worklist_len);

/* Mark non-CV phis as live. Even if the result is unused, we generally cannot remove one
Expand Down Expand Up @@ -664,5 +661,7 @@ int dce_optimize_op_array(zend_op_array *op_array, zend_ssa *ssa, bool reorder_d
}
} FOREACH_PHI_END();

zend_arena_release(&optimizer_ctx->arena, checkpoint);

return removed_ops;
}
2 changes: 1 addition & 1 deletion Zend/Optimizer/dfa_pass.c
Original file line number Diff line number Diff line change
Expand Up @@ -1076,7 +1076,7 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx
}

if (ZEND_OPTIMIZER_PASS_14 & ctx->optimization_level) {
if (dce_optimize_op_array(op_array, ssa, 0)) {
if (dce_optimize_op_array(op_array, ctx, ssa, 0)) {
remove_nops = 1;
}
if (zend_dfa_optimize_jmps(op_array, ssa)) {
Expand Down
2 changes: 1 addition & 1 deletion Zend/Optimizer/zend_optimizer_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ uint32_t zend_optimizer_classify_function(zend_string *name, uint32_t num_args);
void zend_optimizer_migrate_jump(zend_op_array *op_array, zend_op *new_opline, zend_op *opline);
void zend_optimizer_shift_jump(zend_op_array *op_array, zend_op *opline, uint32_t *shiftlist);
int sccp_optimize_op_array(zend_optimizer_ctx *ctx, zend_op_array *op_array, zend_ssa *ssa, zend_call_info **call_map);
int dce_optimize_op_array(zend_op_array *op_array, zend_ssa *ssa, bool reorder_dtor_effects);
int dce_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *optimizer_ctx, zend_ssa *ssa, bool reorder_dtor_effects);
zend_result zend_ssa_escape_analysis(const zend_script *script, zend_op_array *op_array, zend_ssa *ssa);

typedef void (*zend_op_array_func_t)(zend_op_array *, void *context);
Expand Down
45 changes: 22 additions & 23 deletions Zend/zend_portability.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,6 @@

#include <limits.h>

#if HAVE_ALLOCA_H && !defined(_ALLOCA_H)
# include <alloca.h>
#endif

#if defined(ZEND_WIN32) && !defined(__clang__)
#include <intrin.h>
#endif
Expand Down Expand Up @@ -181,6 +177,9 @@
# define ZEND_EXTENSIONS_SUPPORT 0
#endif

#if defined(HAVE_ALLOCA_H) && !defined(_ALLOCA_H)
# include <alloca.h>
#endif
/* AIX requires this to be the first thing in the file. */
#ifndef __GNUC__
# ifndef HAVE_ALLOCA_H
Expand All @@ -194,6 +193,25 @@ char *alloca();
# endif
#endif

#if !ZEND_DEBUG && (defined(HAVE_ALLOCA) || (defined (__GNUC__) && __GNUC__ >= 2)) && !(defined(ZTS) && defined(HPUX)) && !defined(DARWIN)
# define ZEND_ALLOCA_MAX_SIZE (32 * 1024)
# define ALLOCA_FLAG(name) \
bool name;
# define SET_ALLOCA_FLAG(name) \
name = true
# define do_alloca_ex(size, limit, use_heap) \
((use_heap = (UNEXPECTED((size) > (limit)))) ? emalloc(size) : alloca(size))
# define do_alloca(size, use_heap) \
do_alloca_ex(size, ZEND_ALLOCA_MAX_SIZE, use_heap)
# define free_alloca(p, use_heap) \
do { if (UNEXPECTED(use_heap)) efree(p); } while (0)
#else
# define ALLOCA_FLAG(name)
# define SET_ALLOCA_FLAG(name)
# define do_alloca(p, use_heap) emalloc(p)
# define free_alloca(p, use_heap) efree(p)
#endif

#if ZEND_GCC_VERSION >= 2096 || __has_attribute(__malloc__)
# define ZEND_ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
#else
Expand Down Expand Up @@ -345,25 +363,6 @@ char *alloca();
# define XtOffsetOf(s_type, field) offsetof(s_type, field)
#endif

#if (defined(HAVE_ALLOCA) || (defined (__GNUC__) && __GNUC__ >= 2)) && !(defined(ZTS) && defined(HPUX)) && !defined(DARWIN)
# define ZEND_ALLOCA_MAX_SIZE (32 * 1024)
# define ALLOCA_FLAG(name) \
bool name;
# define SET_ALLOCA_FLAG(name) \
name = 1
# define do_alloca_ex(size, limit, use_heap) \
((use_heap = (UNEXPECTED((size) > (limit)))) ? emalloc(size) : alloca(size))
# define do_alloca(size, use_heap) \
do_alloca_ex(size, ZEND_ALLOCA_MAX_SIZE, use_heap)
# define free_alloca(p, use_heap) \
do { if (UNEXPECTED(use_heap)) efree(p); } while (0)
#else
# define ALLOCA_FLAG(name)
# define SET_ALLOCA_FLAG(name)
# define do_alloca(p, use_heap) emalloc(p)
# define free_alloca(p, use_heap) efree(p)
#endif

#ifdef HAVE_SIGSETJMP
# define SETJMP(a) sigsetjmp(a, 0)
# define LONGJMP(a,b) siglongjmp(a, b)
Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -1610,7 +1610,7 @@ PHP_INSTALL_HEADERS([Zend/Optimizer], [ \
PHP_ADD_SOURCES(TSRM, TSRM.c, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1)

PHP_ADD_SOURCES(main, main.c snprintf.c spprintf.c \
fopen_wrappers.c alloca.c php_scandir.c \
fopen_wrappers.c php_scandir.c \
php_ini_builder.c \
php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
strlcat.c explicit_bzero.c reentrancy.c php_variables.c php_ticks.c \
Expand Down
30 changes: 23 additions & 7 deletions ext/standard/crypt_sha256.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

#ifdef PHP_WIN32
# define __alignof__ __alignof
# define alloca _alloca
#else
# ifndef HAVE_ALIGNOF
# include <stddef.h>
Expand Down Expand Up @@ -370,16 +369,23 @@ char * php_sha256_crypt_r(const char *key, const char *salt, char *buffer, int b

salt_len = MIN(strcspn(salt, "$"), SALT_LEN_MAX);
key_len = strlen(key);
char *tmp_key = NULL;
ALLOCA_FLAG(use_heap_key);
char *tmp_salt = NULL;
ALLOCA_FLAG(use_heap_salt);

SET_ALLOCA_FLAG(use_heap_key);
SET_ALLOCA_FLAG(use_heap_salt);

if ((key - (char *) 0) % __alignof__ (uint32_t) != 0) {
char *tmp = (char *) alloca(key_len + __alignof__(uint32_t));
key = copied_key = memcpy(tmp + __alignof__(uint32_t) - (tmp - (char *) 0) % __alignof__(uint32_t), key, key_len);
tmp_key = (char *) do_alloca(key_len + __alignof__(uint32_t), use_heap_key);
key = copied_key = memcpy(tmp_key + __alignof__(uint32_t) - (tmp_key - (char *) 0) % __alignof__(uint32_t), key, key_len);
}

if ((salt - (char *) 0) % __alignof__(uint32_t) != 0) {
char *tmp = (char *) alloca(salt_len + 1 + __alignof__(uint32_t));
tmp_salt = (char *) do_alloca(salt_len + 1 + __alignof__(uint32_t), use_heap_salt);
salt = copied_salt =
memcpy(tmp + __alignof__(uint32_t) - (tmp - (char *) 0) % __alignof__ (uint32_t), salt, salt_len);
memcpy(tmp_salt + __alignof__(uint32_t) - (tmp_salt - (char *) 0) % __alignof__ (uint32_t), salt, salt_len);
copied_salt[salt_len] = 0;
}

Expand Down Expand Up @@ -443,7 +449,8 @@ char * php_sha256_crypt_r(const char *key, const char *salt, char *buffer, int b
sha256_finish_ctx(&alt_ctx, temp_result);

/* Create byte sequence P. */
cp = p_bytes = alloca(key_len);
ALLOCA_FLAG(use_heap_p_bytes);
cp = p_bytes = do_alloca(key_len, use_heap_p_bytes);
for (cnt = key_len; cnt >= 32; cnt -= 32) {
cp = __php_mempcpy((void *)cp, (const void *)temp_result, 32);
}
Expand All @@ -461,7 +468,8 @@ char * php_sha256_crypt_r(const char *key, const char *salt, char *buffer, int b
sha256_finish_ctx(&alt_ctx, temp_result);

/* Create byte sequence S. */
cp = s_bytes = alloca(salt_len);
ALLOCA_FLAG(use_heap_s_bytes);
cp = s_bytes = do_alloca(salt_len, use_heap_s_bytes);
for (cnt = salt_len; cnt >= 32; cnt -= 32) {
cp = __php_mempcpy(cp, temp_result, 32);
}
Expand Down Expand Up @@ -571,6 +579,14 @@ char * php_sha256_crypt_r(const char *key, const char *salt, char *buffer, int b
if (copied_salt != NULL) {
ZEND_SECURE_ZERO(copied_salt, salt_len);
}
if (tmp_key != NULL) {
free_alloca(tmp_key, use_heap_key);
}
if (tmp_salt != NULL) {
free_alloca(tmp_salt, use_heap_salt);
}
free_alloca(p_bytes, use_heap_p_bytes);
free_alloca(s_bytes, use_heap_s_bytes);

return buffer;
}
Expand Down
30 changes: 23 additions & 7 deletions ext/standard/crypt_sha512.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
#include <limits.h>
#ifdef PHP_WIN32
# define __alignof__ __alignof
# define alloca _alloca
#else
# ifndef HAVE_ALIGNOF
# include <stddef.h>
Expand Down Expand Up @@ -404,16 +403,23 @@ php_sha512_crypt_r(const char *key, const char *salt, char *buffer, int buflen)

salt_len = MIN(strcspn(salt, "$"), SALT_LEN_MAX);
key_len = strlen(key);
char *tmp_key = NULL;
ALLOCA_FLAG(use_heap_key);
char *tmp_salt = NULL;
ALLOCA_FLAG(use_heap_salt);

SET_ALLOCA_FLAG(use_heap_key);
SET_ALLOCA_FLAG(use_heap_salt);

if ((key - (char *) 0) % __alignof__ (uint64_t) != 0) {
char *tmp = (char *) alloca (key_len + __alignof__ (uint64_t));
tmp_key = (char *) do_alloca(key_len + __alignof__ (uint64_t), use_heap_key);
key = copied_key =
memcpy(tmp + __alignof__(uint64_t) - (tmp - (char *) 0) % __alignof__(uint64_t), key, key_len);
memcpy(tmp_key + __alignof__(uint64_t) - (tmp_key - (char *) 0) % __alignof__(uint64_t), key, key_len);
}

if ((salt - (char *) 0) % __alignof__ (uint64_t) != 0) {
char *tmp = (char *) alloca(salt_len + 1 + __alignof__(uint64_t));
salt = copied_salt = memcpy(tmp + __alignof__(uint64_t) - (tmp - (char *) 0) % __alignof__(uint64_t), salt, salt_len);
tmp_salt = (char *) do_alloca(salt_len + 1 + __alignof__(uint64_t), use_heap_salt);
salt = copied_salt = memcpy(tmp_salt + __alignof__(uint64_t) - (tmp_salt - (char *) 0) % __alignof__(uint64_t), salt, salt_len);
copied_salt[salt_len] = 0;
}

Expand Down Expand Up @@ -477,7 +483,8 @@ php_sha512_crypt_r(const char *key, const char *salt, char *buffer, int buflen)
sha512_finish_ctx(&alt_ctx, temp_result);

/* Create byte sequence P. */
cp = p_bytes = alloca(key_len);
ALLOCA_FLAG(use_heap_p_bytes);
cp = p_bytes = do_alloca(key_len, use_heap_p_bytes);
for (cnt = key_len; cnt >= 64; cnt -= 64) {
cp = __php_mempcpy((void *) cp, (const void *)temp_result, 64);
}
Expand All @@ -496,7 +503,8 @@ php_sha512_crypt_r(const char *key, const char *salt, char *buffer, int buflen)
sha512_finish_ctx(&alt_ctx, temp_result);

/* Create byte sequence S. */
cp = s_bytes = alloca(salt_len);
ALLOCA_FLAG(use_heap_s_bytes);
cp = s_bytes = do_alloca(salt_len, use_heap_s_bytes);
for (cnt = salt_len; cnt >= 64; cnt -= 64) {
cp = __php_mempcpy(cp, temp_result, 64);
}
Expand Down Expand Up @@ -618,6 +626,14 @@ php_sha512_crypt_r(const char *key, const char *salt, char *buffer, int buflen)
if (copied_salt != NULL) {
ZEND_SECURE_ZERO(copied_salt, salt_len);
}
if (tmp_key != NULL) {
free_alloca(tmp_key, use_heap_key);
}
if (tmp_salt != NULL) {
free_alloca(tmp_salt, use_heap_salt);
}
free_alloca(p_bytes, use_heap_p_bytes);
free_alloca(s_bytes, use_heap_s_bytes);

return buffer;
}
Expand Down
Loading