Skip to content

Commit 7620ea1

Browse files
committed
Don't intern compiled_filename
For php-ast interning the file name is an effective memory leak, see php-ast#134. I don't think there's any reason to do this. At some point this was needed due to bugs in the interned string mechanism that caused issues if the string was later interned, e.g. through a __FILE__ reference. These issues have since been resolved. In conjunction with the filenames_table removal in c4016ec this means that filenames now need to be refcounted like normal strings. In particular the filename reference in op_arrays and CEs are refcounted.
1 parent c4016ec commit 7620ea1

File tree

5 files changed

+16
-15
lines changed

5 files changed

+16
-15
lines changed

Zend/zend_compile.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -442,14 +442,17 @@ void shutdown_compiler(void) /* {{{ */
442442

443443
ZEND_API zend_string *zend_set_compiled_filename(zend_string *new_compiled_filename) /* {{{ */
444444
{
445-
new_compiled_filename = zend_new_interned_string(zend_string_copy(new_compiled_filename));
446-
CG(compiled_filename) = new_compiled_filename;
445+
CG(compiled_filename) = zend_string_copy(new_compiled_filename);
447446
return new_compiled_filename;
448447
}
449448
/* }}} */
450449

451450
ZEND_API void zend_restore_compiled_filename(zend_string *original_compiled_filename) /* {{{ */
452451
{
452+
if (CG(compiled_filename)) {
453+
zend_string_release(CG(compiled_filename));
454+
CG(compiled_filename) = NULL;
455+
}
453456
CG(compiled_filename) = original_compiled_filename;
454457
}
455458
/* }}} */
@@ -7345,7 +7348,7 @@ void zend_compile_class_decl(znode *result, zend_ast *ast, zend_bool toplevel) /
73457348
}
73467349

73477350
ce->ce_flags |= decl->flags;
7348-
ce->info.user.filename = zend_get_compiled_filename();
7351+
ce->info.user.filename = zend_string_copy(zend_get_compiled_filename());
73497352
ce->info.user.line_start = decl->start_lineno;
73507353
ce->info.user.line_end = decl->end_lineno;
73517354

Zend/zend_language_scanner.l

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,8 +233,9 @@ ZEND_API void zend_save_lexical_state(zend_lex_state *lex_state)
233233

234234
lex_state->in = SCNG(yy_in);
235235
lex_state->yy_state = YYSTATE;
236-
lex_state->filename = zend_get_compiled_filename();
236+
lex_state->filename = CG(compiled_filename);
237237
lex_state->lineno = CG(zend_lineno);
238+
CG(compiled_filename) = NULL;
238239

239240
lex_state->script_org = SCNG(script_org);
240241
lex_state->script_org_size = SCNG(script_org_size);

Zend/zend_opcode.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_siz
6161
op_array->T = 0;
6262

6363
op_array->function_name = NULL;
64-
op_array->filename = zend_get_compiled_filename();
64+
op_array->filename = zend_string_copy(zend_get_compiled_filename());
6565
op_array->doc_comment = NULL;
6666
op_array->attributes = NULL;
6767

@@ -354,6 +354,7 @@ ZEND_API void destroy_zend_class(zval *zv)
354354
}
355355
efree(ce->interfaces);
356356
}
357+
zend_string_release_ex(ce->info.user.filename, 0);
357358
if (ce->info.user.doc_comment) {
358359
zend_string_release_ex(ce->info.user.doc_comment, 0);
359360
}
@@ -496,6 +497,7 @@ ZEND_API void destroy_op_array(zend_op_array *op_array)
496497
}
497498
efree(op_array->opcodes);
498499

500+
zend_string_release_ex(op_array->filename, 0);
499501
if (op_array->doc_comment) {
500502
zend_string_release_ex(op_array->doc_comment, 0);
501503
}

ext/opcache/ZendAccelerator.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4528,7 +4528,6 @@ static int accel_preload(const char *config, zend_bool in_child)
45284528

45294529
if (ret == SUCCESS) {
45304530
zend_persistent_script *script;
4531-
zend_string *filename;
45324531
int ping_auto_globals_mask;
45334532
int i;
45344533
zend_class_entry *ce;
@@ -4668,7 +4667,7 @@ static int accel_preload(const char *config, zend_bool in_child)
46684667
script->ping_auto_globals_mask = ping_auto_globals_mask;
46694668

46704669
/* Store all functions and classes in a single pseudo-file */
4671-
filename = zend_string_init("$PRELOAD$", sizeof("$PRELOAD$") - 1, 0);
4670+
CG(compiled_filename) = zend_string_init("$PRELOAD$", sizeof("$PRELOAD$") - 1, 0);
46724671
#if ZEND_USE_ABS_CONST_ADDR
46734672
init_op_array(&script->script.main_op_array, ZEND_USER_FUNCTION, 1);
46744673
#else
@@ -4690,8 +4689,8 @@ static int accel_preload(const char *config, zend_bool in_child)
46904689
ZEND_PASS_TWO_UPDATE_CONSTANT(&script->script.main_op_array, script->script.main_op_array.opcodes, script->script.main_op_array.opcodes[0].op1);
46914690
zend_vm_set_opcode_handler(script->script.main_op_array.opcodes);
46924691

4693-
script->script.main_op_array.filename = filename;
4694-
script->script.filename = zend_string_copy(filename);
4692+
script->script.filename = CG(compiled_filename);
4693+
CG(compiled_filename) = NULL;
46954694

46964695
script->script.first_early_binding_opline = (uint32_t)-1;
46974696

@@ -4728,8 +4727,6 @@ static int accel_preload(const char *config, zend_bool in_child)
47284727
SHM_PROTECT();
47294728
HANDLE_UNBLOCK_INTERRUPTIONS();
47304729

4731-
zend_string_release(filename);
4732-
47334730
ZEND_ASSERT(ZCSG(preload_script)->arena_size == 0);
47344731

47354732
preload_load();

ext/opcache/zend_persist.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -565,8 +565,7 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc
565565
}
566566

567567
if (op_array->filename) {
568-
/* do not free! PHP has centralized filename storage, compiler will free it */
569-
zend_accel_memdup_string(op_array->filename);
568+
zend_accel_store_string(op_array->filename);
570569
}
571570

572571
if (op_array->arg_info) {
@@ -864,8 +863,7 @@ static void zend_persist_class_entry(zval *zv)
864863
HT_FLAGS(&ce->constants_table) &= (HASH_FLAG_UNINITIALIZED | HASH_FLAG_STATIC_KEYS);
865864

866865
if (ce->info.user.filename) {
867-
/* do not free! PHP has centralized filename storage, compiler will free it */
868-
zend_accel_memdup_string(ce->info.user.filename);
866+
zend_accel_store_string(ce->info.user.filename);
869867
}
870868
if (ce->info.user.doc_comment) {
871869
if (ZCG(accel_directives).save_comments) {

0 commit comments

Comments
 (0)