Skip to content

Commit

Permalink
Change Zend Stream API to use zend_string* instead of char*.
Browse files Browse the repository at this point in the history
This allows to eliminate re-calculation of string lenght and hash value.
See the detailed list of changes in UPGRADING.INTERNALS.
  • Loading branch information
dstogov committed Mar 16, 2021
1 parent 9bbeb05 commit c732ab4
Show file tree
Hide file tree
Showing 45 changed files with 441 additions and 404 deletions.
15 changes: 15 additions & 0 deletions UPGRADING.INTERNALS
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ PHP 8.1 INTERNALS UPGRADE NOTES

1. Internal API changes
a. Removed Zend APIs
b. Zend Stream API

2. Build system changes

Expand All @@ -16,6 +17,20 @@ PHP 8.1 INTERNALS UPGRADE NOTES
spl_ce_Stringable, spl_ce_Traversable alias class entries have been removed in favor of zend_ce_aggregate,
zend_ce_arrayaccess, zend_ce_countable, zend_ce_iterator, zend_ce_serializable, zend_ce_stringable,
zend_ce_traversable.
b. Zend Stream API has been changed to use "zend_string*" instead of "char*"
- zend_file_handle.filename now is zend_string*
- zend_file_handle.free_filename is removed. Now zend_file_handle.filename is always released.
- added zend_file_handle.primary_script flag. SAPIs should set it for main executed script.
- added zend_file_handle.in_list flag, which is set when a file_handle is added into CG(open_files)
- added zend_stream_init_filename_ex() function, that takes filename as zend_string*
- the "filename" parameter of functons zend_stream_open(), php_stream_open_for_zend_ex() and
callback zend_stream_open_function() has been removed (it's now passed as a "filename" field of the
file_handle parameter)
- in zend_fopen() and zend_resolve_path() callbacks filename now passed as zend_string*
- file_handles should be destroyed by zend_destroy_file_handle() function (usually in the same function
the same function where they were created by zend_stream_init_*()). Previously there were two different
destructors zend_destroy_file_handle() and zend_file_handle_dtor().
- zend_ini_scanner_globals.filename now is zend_string*

========================
2. Build system changes
Expand Down
16 changes: 6 additions & 10 deletions Zend/zend.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,15 @@ static uint32_t zend_version_info_length;
ZEND_API zend_class_entry *zend_standard_class_def = NULL;
ZEND_API size_t (*zend_printf)(const char *format, ...);
ZEND_API zend_write_func_t zend_write;
ZEND_API FILE *(*zend_fopen)(const char *filename, zend_string **opened_path);
ZEND_API zend_result (*zend_stream_open_function)(const char *filename, zend_file_handle *handle);
ZEND_API FILE *(*zend_fopen)(zend_string *filename, zend_string **opened_path);
ZEND_API zend_result (*zend_stream_open_function)(zend_file_handle *handle);
ZEND_API void (*zend_ticks_function)(int ticks);
ZEND_API void (*zend_interrupt_function)(zend_execute_data *execute_data);
ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint32_t error_lineno, zend_string *message);
void (*zend_printf_to_smart_string)(smart_string *buf, const char *format, va_list ap);
void (*zend_printf_to_smart_str)(smart_str *buf, const char *format, va_list ap);
ZEND_API char *(*zend_getenv)(const char *name, size_t name_len);
ZEND_API zend_string *(*zend_resolve_path)(const char *filename, size_t filename_len);
ZEND_API zend_string *(*zend_resolve_path)(zend_string *filename);
ZEND_API zend_result (*zend_post_startup_cb)(void) = NULL;
ZEND_API void (*zend_post_shutdown_cb)(void) = NULL;
ZEND_API zend_result (*zend_preload_autoload)(zend_string *filename) = NULL;
Expand Down Expand Up @@ -515,12 +515,12 @@ ZEND_API void zend_print_zval_r(zval *expr, int indent) /* {{{ */
}
/* }}} */

static FILE *zend_fopen_wrapper(const char *filename, zend_string **opened_path) /* {{{ */
static FILE *zend_fopen_wrapper(zend_string *filename, zend_string **opened_path) /* {{{ */
{
if (opened_path) {
*opened_path = zend_string_init(filename, strlen(filename), 0);
*opened_path = zend_string_copy(filename);
}
return fopen(filename, "rb");
return fopen(ZSTR_VAL(filename), "rb");
}
/* }}} */

Expand Down Expand Up @@ -1674,17 +1674,13 @@ ZEND_API zend_result zend_execute_scripts(int type, zval *retval, int file_count
}

if (ret == FAILURE) {
/* If a failure occurred in one of the earlier files,
* only destroy the following file handles. */
zend_file_handle_dtor(file_handle);
continue;
}

op_array = zend_compile_file(file_handle, type);
if (file_handle->opened_path) {
zend_hash_add_empty_element(&EG(included_files), file_handle->opened_path);
}
zend_destroy_file_handle(file_handle);
if (op_array) {
zend_execute(op_array, retval);
zend_exception_restore();
Expand Down
12 changes: 6 additions & 6 deletions Zend/zend.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,16 +215,16 @@ typedef struct _zend_utility_functions {
void (*error_function)(int type, const char *error_filename, const uint32_t error_lineno, zend_string *message);
size_t (*printf_function)(const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 1, 2);
size_t (*write_function)(const char *str, size_t str_length);
FILE *(*fopen_function)(const char *filename, zend_string **opened_path);
FILE *(*fopen_function)(zend_string *filename, zend_string **opened_path);
void (*message_handler)(zend_long message, const void *data);
zval *(*get_configuration_directive)(zend_string *name);
void (*ticks_function)(int ticks);
void (*on_timeout)(int seconds);
zend_result (*stream_open_function)(const char *filename, zend_file_handle *handle);
zend_result (*stream_open_function)(zend_file_handle *handle);
void (*printf_to_smart_string_function)(smart_string *buf, const char *format, va_list ap);
void (*printf_to_smart_str_function)(smart_str *buf, const char *format, va_list ap);
char *(*getenv_function)(const char *name, size_t name_len);
zend_string *(*resolve_path_function)(const char *filename, size_t filename_len);
zend_string *(*resolve_path_function)(zend_string *filename);
} zend_utility_functions;

typedef struct _zend_utility_values {
Expand Down Expand Up @@ -303,16 +303,16 @@ END_EXTERN_C()
BEGIN_EXTERN_C()
extern ZEND_API size_t (*zend_printf)(const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 1, 2);
extern ZEND_API zend_write_func_t zend_write;
extern ZEND_API FILE *(*zend_fopen)(const char *filename, zend_string **opened_path);
extern ZEND_API FILE *(*zend_fopen)(zend_string *filename, zend_string **opened_path);
extern ZEND_API void (*zend_ticks_function)(int ticks);
extern ZEND_API void (*zend_interrupt_function)(zend_execute_data *execute_data);
extern ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint32_t error_lineno, zend_string *message);
extern ZEND_API void (*zend_on_timeout)(int seconds);
extern ZEND_API zend_result (*zend_stream_open_function)(const char *filename, zend_file_handle *handle);
extern ZEND_API zend_result (*zend_stream_open_function)(zend_file_handle *handle);
extern void (*zend_printf_to_smart_string)(smart_string *buf, const char *format, va_list ap);
extern void (*zend_printf_to_smart_str)(smart_str *buf, const char *format, va_list ap);
extern ZEND_API char *(*zend_getenv)(const char *name, size_t name_len);
extern ZEND_API zend_string *(*zend_resolve_path)(const char *filename, size_t filename_len);
extern ZEND_API zend_string *(*zend_resolve_path)(zend_string *filename);

/* These two callbacks are especially for opcache */
extern ZEND_API zend_result (*zend_post_startup_cb)(void);
Expand Down
9 changes: 1 addition & 8 deletions Zend/zend_compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -398,21 +398,14 @@ static bool zend_have_seen_symbol(zend_string *name, uint32_t kind) {
return zv && (Z_LVAL_P(zv) & kind) != 0;
}

ZEND_API void file_handle_dtor(zend_file_handle *fh) /* {{{ */
{

zend_file_handle_dtor(fh);
}
/* }}} */

void init_compiler(void) /* {{{ */
{
CG(arena) = zend_arena_create(64 * 1024);
CG(active_op_array) = NULL;
memset(&CG(context), 0, sizeof(CG(context)));
zend_init_compiler_data_structures();
zend_init_rsrc_list();
zend_llist_init(&CG(open_files), sizeof(zend_file_handle), (void (*)(void *)) file_handle_dtor, 0);
zend_stream_init();
CG(unclean_shutdown) = 0;

CG(delayed_variance_obligations) = NULL;
Expand Down
4 changes: 2 additions & 2 deletions Zend/zend_dtrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ static inline const char *dtrace_get_executed_filename(void)
ZEND_API zend_op_array *dtrace_compile_file(zend_file_handle *file_handle, int type)
{
zend_op_array *res;
DTRACE_COMPILE_FILE_ENTRY(ZSTR_VAL(file_handle->opened_path), (char *)file_handle->filename);
DTRACE_COMPILE_FILE_ENTRY(ZSTR_VAL(file_handle->opened_path), ZSTR_VAL(file_handle->filename));
res = compile_file(file_handle, type);
DTRACE_COMPILE_FILE_RETURN(ZSTR_VAL(file_handle->opened_path), (char *)file_handle->filename);
DTRACE_COMPILE_FILE_RETURN(ZSTR_VAL(file_handle->opened_path), ZSTR_VAL(file_handle->filename));

return res;
}
Expand Down
12 changes: 7 additions & 5 deletions Zend/zend_execute.c
Original file line number Diff line number Diff line change
Expand Up @@ -4222,10 +4222,12 @@ static zend_never_inline zend_op_array* ZEND_FASTCALL zend_include_or_eval(zval
zend_file_handle file_handle;
zend_string *resolved_path;

resolved_path = zend_resolve_path(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename));
resolved_path = zend_resolve_path(Z_STR_P(inc_filename));
if (EXPECTED(resolved_path)) {
if (zend_hash_exists(&EG(included_files), resolved_path)) {
goto already_compiled;
new_op_array = ZEND_FAKE_OP_ARRAY;
zend_string_release_ex(resolved_path, 0);
break;
}
} else if (UNEXPECTED(EG(exception))) {
break;
Expand All @@ -4239,7 +4241,8 @@ static zend_never_inline zend_op_array* ZEND_FASTCALL zend_include_or_eval(zval
resolved_path = zend_string_copy(Z_STR_P(inc_filename));
}

if (SUCCESS == zend_stream_open(ZSTR_VAL(resolved_path), &file_handle)) {
zend_stream_init_filename_ex(&file_handle, resolved_path);
if (SUCCESS == zend_stream_open(&file_handle)) {

if (!file_handle.opened_path) {
file_handle.opened_path = zend_string_copy(resolved_path);
Expand All @@ -4254,8 +4257,6 @@ static zend_never_inline zend_op_array* ZEND_FASTCALL zend_include_or_eval(zval
}
return op_array;
} else {
zend_file_handle_dtor(&file_handle);
already_compiled:
new_op_array = ZEND_FAKE_OP_ARRAY;
}
} else if (!EG(exception)) {
Expand All @@ -4264,6 +4265,7 @@ static zend_never_inline zend_op_array* ZEND_FASTCALL zend_include_or_eval(zval
ZMSG_FAILED_INCLUDE_FOPEN : ZMSG_FAILED_REQUIRE_FOPEN,
Z_STRVAL_P(inc_filename));
}
zend_destroy_file_handle(&file_handle);
zend_string_release_ex(resolved_path, 0);
}
break;
Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_execute_API.c
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ void shutdown_executor(void) /* {{{ */
#endif

zend_try {
zend_llist_destroy(&CG(open_files));
zend_stream_shutdown();
} zend_end_try();

EG(flags) |= EG_FLAGS_IN_RESOURCE_SHUTDOWN;
Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ struct _zend_ini_scanner_globals {
int yy_state;
zend_stack state_stack;

char *filename;
zend_string *filename;
int lineno;

/* Modes are: ZEND_INI_SCANNER_NORMAL, ZEND_INI_SCANNER_RAW, ZEND_INI_SCANNER_TYPED */
Expand Down
1 change: 0 additions & 1 deletion Zend/zend_ini_parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,6 @@ ZEND_API zend_result zend_parse_ini_file(zend_file_handle *fh, bool unbuffered_e

CG(ini_parser_unbuffered_errors) = unbuffered_errors;
retval = ini_parse();
zend_file_handle_dtor(fh);

shutdown_ini_scanner();

Expand Down
7 changes: 3 additions & 4 deletions Zend/zend_ini_scanner.l
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ static zend_result init_ini_scanner(int scanner_mode, zend_file_handle *fh)
SCNG(yy_in) = fh;

if (fh != NULL) {
ini_filename = zend_strndup(fh->filename, strlen(fh->filename));
ini_filename = zend_string_copy(fh->filename);
} else {
ini_filename = NULL;
}
Expand All @@ -248,7 +248,7 @@ void shutdown_ini_scanner(void)
{
zend_stack_destroy(&SCNG(state_stack));
if (ini_filename) {
free(ini_filename);
zend_string_release(ini_filename);
}
}
/* }}} */
Expand All @@ -263,7 +263,7 @@ ZEND_COLD int zend_ini_scanner_get_lineno(void)
/* {{{ zend_ini_scanner_get_filename() */
ZEND_COLD char *zend_ini_scanner_get_filename(void)
{
return ini_filename ? ini_filename : "Unknown";
return ini_filename ? ZSTR_VAL(ini_filename) : "Unknown";
}
/* }}} */

Expand All @@ -278,7 +278,6 @@ zend_result zend_ini_open_file_for_scanning(zend_file_handle *fh, int scanner_mo
}

if (init_ini_scanner(scanner_mode, fh) == FAILURE) {
zend_file_handle_dtor(fh);
return FAILURE;
}

Expand Down
21 changes: 7 additions & 14 deletions Zend/zend_language_scanner.l
Original file line number Diff line number Diff line change
Expand Up @@ -297,16 +297,6 @@ ZEND_API void zend_restore_lexical_state(zend_lex_state *lex_state)
RESET_DOC_COMMENT();
}

ZEND_API void zend_destroy_file_handle(zend_file_handle *file_handle)
{
zend_llist_del_element(&CG(open_files), file_handle, (int (*)(void *, void *)) zend_compare_file_handles);
/* zend_file_handle_dtor() operates on the copy, so we have to NULLify the original here */
file_handle->opened_path = NULL;
if (file_handle->free_filename) {
file_handle->filename = NULL;
}
}

ZEND_API zend_result zend_lex_tstring(zval *zv, unsigned char *ident)
{
unsigned char *end = ident;
Expand Down Expand Up @@ -542,11 +532,13 @@ ZEND_API zend_result open_file_for_scanning(zend_file_handle *file_handle)
if (zend_stream_fixup(file_handle, &buf, &size) == FAILURE) {
/* Still add it to open_files to make destroy_file_handle work */
zend_llist_add_element(&CG(open_files), file_handle);
file_handle->in_list = 1;
return FAILURE;
}

ZEND_ASSERT(!EG(exception) && "stream_fixup() should have failed");
zend_llist_add_element(&CG(open_files), file_handle);
file_handle->in_list = 1;

/* Reset the scanner for scanning the new file */
SCNG(yy_in) = file_handle;
Expand Down Expand Up @@ -584,7 +576,7 @@ ZEND_API zend_result open_file_for_scanning(zend_file_handle *file_handle)
if (file_handle->opened_path) {
compiled_filename = zend_string_copy(file_handle->opened_path);
} else {
compiled_filename = zend_string_init(file_handle->filename, strlen(file_handle->filename), 0);
compiled_filename = zend_string_copy(file_handle->filename);
}

zend_set_compiled_filename(compiled_filename);
Expand Down Expand Up @@ -655,9 +647,9 @@ ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type)
if (open_file_for_scanning(file_handle)==FAILURE) {
if (!EG(exception)) {
if (type==ZEND_REQUIRE) {
zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, file_handle->filename);
zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, ZSTR_VAL(file_handle->filename));
} else {
zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, file_handle->filename);
zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, ZSTR_VAL(file_handle->filename));
}
}
} else {
Expand Down Expand Up @@ -715,7 +707,7 @@ zend_op_array *compile_filename(int type, zval *filename)
ZVAL_STR(&tmp, zval_get_string(filename));
filename = &tmp;
}
zend_stream_init_filename(&file_handle, Z_STRVAL_P(filename));
zend_stream_init_filename_ex(&file_handle, Z_STR_P(filename));

retval = zend_compile_file(&file_handle, type);
if (retval && file_handle.handle.stream.handle) {
Expand Down Expand Up @@ -837,6 +829,7 @@ zend_result highlight_file(const char *filename, zend_syntax_highlighter_ini *sy
zend_save_lexical_state(&original_lex_state);
if (open_file_for_scanning(&file_handle)==FAILURE) {
zend_message_dispatcher(ZMSG_FAILED_HIGHLIGHT_FOPEN, filename);
zend_destroy_file_handle(&file_handle);
zend_restore_lexical_state(&original_lex_state);
return FAILURE;
}
Expand Down
2 changes: 2 additions & 0 deletions Zend/zend_llist.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ ZEND_API void zend_llist_destroy(zend_llist *l)
current = next;
}

l->head = NULL;
l->tail = NULL;
l->count = 0;
}

Expand Down

0 comments on commit c732ab4

Please sign in to comment.