Skip to content

Commit 6a6e91f

Browse files
authored
Shrink some commonly used structs by reordering members (#10880)
Struct members require some alignment based on their type. This means that if a struct member is not aligned, there will be a hole created by the compiler in the struct, which is wasted space. This patch reorders some of the most commonly used structs, but in such a way that the fields which were in the same cache line still belong together. The only exception to this is exception_ignore_args, which was temporally not close to nearby members, and as such I placed it further up to close a hole. On 64-bit Linux this gives us the following shrinks: * zend_op_array: 248 -> 240 * zend_ssa_var: 56 -> 48 * zend_ssa_var_info: 48 -> 40 * php_core_globals: 672 -> 608 * zend_executor_globals: 1824 -> 1792 On 32-bit, the sizes will either remain the same or will result in smaller shrinks.
1 parent 7eee0d1 commit 6a6e91f

File tree

6 files changed

+48
-41
lines changed

6 files changed

+48
-41
lines changed

UPGRADING.INTERNALS

+3
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ PHP 8.3 INTERNALS UPGRADE NOTES
3939
- zend_fiber_init_context()
4040
* The fast_add_function() has been removed, use add_function() that will
4141
call the static inline add_function_fast() instead.
42+
* The order of members of zend_op_array, zend_ssa_var, zend_ssa_var_info,
43+
zend_executor_globals and php_core_globals have changed to improve
44+
struct packing which reduces their size.
4245

4346
========================
4447
2. Build system changes

Zend/Optimizer/zend_ssa.h

+9-9
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,8 @@ typedef struct _zend_ssa_var {
110110
int var; /* original var number; op.var for CVs and following numbers for VARs and TMP_VARs */
111111
int scc; /* strongly connected component */
112112
int definition; /* opcode that defines this value */
113-
zend_ssa_phi *definition_phi; /* phi that defines this value */
114113
int use_chain; /* uses of this value, linked through opN_use_chain */
114+
zend_ssa_phi *definition_phi; /* phi that defines this value */
115115
zend_ssa_phi *phi_use_chain; /* uses of this value in Phi, linked through use_chain */
116116
zend_ssa_phi *sym_use_chain; /* uses of this value in Pi constraints */
117117
unsigned int no_val : 1; /* value doesn't matter (used as op1 in ZEND_ASSIGN) */
@@ -122,16 +122,16 @@ typedef struct _zend_ssa_var {
122122

123123
typedef struct _zend_ssa_var_info {
124124
uint32_t type; /* inferred type (see zend_inference.h) */
125+
bool has_range : 1;
126+
bool is_instanceof : 1; /* 0 - class == "ce", 1 - may be child of "ce" */
127+
bool recursive : 1;
128+
bool use_as_double : 1;
129+
bool delayed_fetch_this : 1;
130+
bool avoid_refcounting : 1;
131+
bool guarded_reference : 1;
132+
bool indirect_reference : 1; /* IS_INDIRECT returned by FETCH_DIM_W/FETCH_OBJ_W */
125133
zend_ssa_range range;
126134
zend_class_entry *ce;
127-
unsigned int has_range : 1;
128-
unsigned int is_instanceof : 1; /* 0 - class == "ce", 1 - may be child of "ce" */
129-
unsigned int recursive : 1;
130-
unsigned int use_as_double : 1;
131-
unsigned int delayed_fetch_this : 1;
132-
unsigned int avoid_refcounting : 1;
133-
unsigned int guarded_reference : 1;
134-
unsigned int indirect_reference : 1; /* IS_INDIRECT returned by FETCH_DIM_W/FETCH_OBJ_W */
135135
} zend_ssa_var_info;
136136

137137
typedef struct _zend_ssa {

Zend/zend_compile.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -448,8 +448,8 @@ struct _zend_op_array {
448448
uint32_t required_num_args;
449449
zend_arg_info *arg_info;
450450
HashTable *attributes;
451-
uint32_t T; /* number of temporary variables */
452451
ZEND_MAP_PTR_DEF(void **, run_time_cache);
452+
uint32_t T; /* number of temporary variables */
453453
/* END of common elements */
454454

455455
int cache_size; /* number of run_time_cache_slots * sizeof(void*) */
@@ -503,8 +503,8 @@ typedef struct _zend_internal_function {
503503
uint32_t required_num_args;
504504
zend_internal_arg_info *arg_info;
505505
HashTable *attributes;
506-
uint32_t T; /* number of temporary variables */
507506
ZEND_MAP_PTR_DEF(void **, run_time_cache);
507+
uint32_t T; /* number of temporary variables */
508508
/* END of common elements */
509509

510510
zif_handler handler;
@@ -529,8 +529,8 @@ union _zend_function {
529529
uint32_t required_num_args;
530530
zend_arg_info *arg_info; /* index -1 represents the return value info, if any */
531531
HashTable *attributes;
532-
uint32_t T; /* number of temporary variables */
533532
ZEND_MAP_PTR_DEF(void **, run_time_cache);
533+
uint32_t T; /* number of temporary variables */
534534
} common;
535535

536536
zend_op_array op_array;

Zend/zend_execute.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,8 @@ ZEND_API const zend_internal_function zend_pass_function = {
145145
0, /* required_num_args */
146146
(zend_internal_arg_info *) zend_pass_function_arg_info + 1, /* arg_info */
147147
NULL, /* attributes */
148-
0, /* T */
149148
NULL, /* run_time_cache */
149+
0, /* T */
150150
ZEND_FN(pass), /* handler */
151151
NULL, /* module */
152152
{NULL,NULL,NULL,NULL} /* reserved */

Zend/zend_globals.h

+11-9
Original file line numberDiff line numberDiff line change
@@ -193,22 +193,24 @@ struct _zend_executor_globals {
193193

194194
uint32_t jit_trace_num; /* Used by tracing JIT to reference the currently running trace */
195195

196-
zend_long precision;
197-
198196
int ticks_count;
199197

198+
zend_long precision;
199+
200200
uint32_t persistent_constants_count;
201201
uint32_t persistent_functions_count;
202202
uint32_t persistent_classes_count;
203203

204-
HashTable *in_autoload;
205-
bool full_tables_cleanup;
206-
207204
/* for extended information support */
208205
bool no_extensions;
209206

207+
bool full_tables_cleanup;
208+
210209
zend_atomic_bool vm_interrupt;
211210
zend_atomic_bool timed_out;
211+
212+
HashTable *in_autoload;
213+
212214
zend_long hard_timeout;
213215
void *stack_base;
214216
void *stack_limit;
@@ -221,20 +223,21 @@ struct _zend_executor_globals {
221223
HashTable persistent_list;
222224

223225
int user_error_handler_error_reporting;
226+
bool exception_ignore_args;
224227
zval user_error_handler;
225228
zval user_exception_handler;
226229
zend_stack user_error_handlers_error_reporting;
227230
zend_stack user_error_handlers;
228231
zend_stack user_exception_handlers;
229232

230-
zend_error_handling_t error_handling;
231233
zend_class_entry *exception_class;
234+
zend_error_handling_t error_handling;
235+
236+
int capture_warnings_during_sccp;
232237

233238
/* timeout support */
234239
zend_long timeout_seconds;
235240

236-
int capture_warnings_during_sccp;
237-
238241
HashTable *ini_directives;
239242
HashTable *modified_ini_directives;
240243
zend_ini_entry *error_reporting_ini_entry;
@@ -266,7 +269,6 @@ struct _zend_executor_globals {
266269

267270
HashTable weakrefs;
268271

269-
bool exception_ignore_args;
270272
zend_long exception_string_param_max_len;
271273

272274
zend_get_gc_buffer get_gc_buffer;

main/php_globals.h

+21-19
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,19 @@ typedef struct _arg_separators {
5353
} arg_separators;
5454

5555
struct _php_core_globals {
56-
bool implicit_flush;
57-
5856
zend_long output_buffering;
5957

58+
bool implicit_flush;
59+
6060
bool enable_dl;
6161

62+
uint8_t display_errors;
63+
bool display_startup_errors;
64+
bool log_errors;
65+
bool ignore_repeated_errors;
66+
bool ignore_repeated_source;
67+
bool report_memleaks;
68+
6269
char *output_handler;
6370

6471
char *unserialize_callback_func;
@@ -67,12 +74,6 @@ struct _php_core_globals {
6774
zend_long memory_limit;
6875
zend_long max_input_time;
6976

70-
uint8_t display_errors;
71-
bool display_startup_errors;
72-
bool log_errors;
73-
bool ignore_repeated_errors;
74-
bool ignore_repeated_source;
75-
bool report_memleaks;
7677
char *error_log;
7778

7879
char *doc_root;
@@ -116,12 +117,12 @@ struct _php_core_globals {
116117
bool register_argc_argv;
117118
bool auto_globals_jit;
118119

119-
char *docref_root;
120-
char *docref_ext;
121-
122120
bool html_errors;
123121
bool xmlrpc_errors;
124122

123+
char *docref_root;
124+
char *docref_ext;
125+
125126
zend_long xmlrpc_error_number;
126127

127128
bool activated_auto_globals[8];
@@ -134,39 +135,40 @@ struct _php_core_globals {
134135
bool report_zend_debug;
135136

136137
int last_error_type;
138+
int last_error_lineno;
137139
zend_string *last_error_message;
138140
zend_string *last_error_file;
139-
int last_error_lineno;
140141

141142
char *php_sys_temp_dir;
142143

143144
char *disable_classes;
144-
bool allow_url_include;
145-
#ifdef PHP_WIN32
146-
bool com_initialized;
147-
#endif
148145
zend_long max_input_nesting_level;
149146
zend_long max_input_vars;
150-
bool in_user_include;
151147

152148
char *user_ini_filename;
153149
zend_long user_ini_cache_ttl;
154150

155151
char *request_order;
156152

153+
char *mail_log;
157154
bool mail_x_header;
158155
bool mail_mixed_lf_and_crlf;
159-
char *mail_log;
160156

161157
bool in_error_log;
162158

159+
bool allow_url_include;
160+
#ifdef PHP_WIN32
161+
bool com_initialized;
162+
#endif
163+
bool in_user_include;
164+
163165
#ifdef PHP_WIN32
164166
bool windows_show_crt_warning;
165167
#endif
166168

169+
bool have_called_openlog;
167170
zend_long syslog_facility;
168171
char *syslog_ident;
169-
bool have_called_openlog;
170172
zend_long syslog_filter;
171173
zend_long error_log_mode;
172174
};

0 commit comments

Comments
 (0)