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
c4016ecd446ef26bb3dc77735b6e441e151ea985
this means that filenames now need to be refcounted like normal
strings. In particular the filename reference in op_arrays and CEs
are refcounted.
ZEND_API zend_string *zend_set_compiled_filename(zend_string *new_compiled_filename) /* {{{ */
{
- new_compiled_filename = zend_new_interned_string(zend_string_copy(new_compiled_filename));
- CG(compiled_filename) = new_compiled_filename;
+ CG(compiled_filename) = zend_string_copy(new_compiled_filename);
return new_compiled_filename;
}
/* }}} */
ZEND_API void zend_restore_compiled_filename(zend_string *original_compiled_filename) /* {{{ */
{
+ if (CG(compiled_filename)) {
+ zend_string_release(CG(compiled_filename));
+ CG(compiled_filename) = NULL;
+ }
CG(compiled_filename) = original_compiled_filename;
}
/* }}} */
}
ce->ce_flags |= decl->flags;
- ce->info.user.filename = zend_get_compiled_filename();
+ ce->info.user.filename = zend_string_copy(zend_get_compiled_filename());
ce->info.user.line_start = decl->start_lineno;
ce->info.user.line_end = decl->end_lineno;
lex_state->in = SCNG(yy_in);
lex_state->yy_state = YYSTATE;
- lex_state->filename = zend_get_compiled_filename();
+ lex_state->filename = CG(compiled_filename);
lex_state->lineno = CG(zend_lineno);
+ CG(compiled_filename) = NULL;
lex_state->script_org = SCNG(script_org);
lex_state->script_org_size = SCNG(script_org_size);
op_array->T = 0;
op_array->function_name = NULL;
- op_array->filename = zend_get_compiled_filename();
+ op_array->filename = zend_string_copy(zend_get_compiled_filename());
op_array->doc_comment = NULL;
op_array->attributes = NULL;
}
efree(ce->interfaces);
}
+ zend_string_release_ex(ce->info.user.filename, 0);
if (ce->info.user.doc_comment) {
zend_string_release_ex(ce->info.user.doc_comment, 0);
}
}
efree(op_array->opcodes);
+ zend_string_release_ex(op_array->filename, 0);
if (op_array->doc_comment) {
zend_string_release_ex(op_array->doc_comment, 0);
}
if (ret == SUCCESS) {
zend_persistent_script *script;
- zend_string *filename;
int ping_auto_globals_mask;
int i;
zend_class_entry *ce;
script->ping_auto_globals_mask = ping_auto_globals_mask;
/* Store all functions and classes in a single pseudo-file */
- filename = zend_string_init("$PRELOAD$", sizeof("$PRELOAD$") - 1, 0);
+ CG(compiled_filename) = zend_string_init("$PRELOAD$", sizeof("$PRELOAD$") - 1, 0);
#if ZEND_USE_ABS_CONST_ADDR
init_op_array(&script->script.main_op_array, ZEND_USER_FUNCTION, 1);
#else
ZEND_PASS_TWO_UPDATE_CONSTANT(&script->script.main_op_array, script->script.main_op_array.opcodes, script->script.main_op_array.opcodes[0].op1);
zend_vm_set_opcode_handler(script->script.main_op_array.opcodes);
- script->script.main_op_array.filename = filename;
- script->script.filename = zend_string_copy(filename);
+ script->script.filename = CG(compiled_filename);
+ CG(compiled_filename) = NULL;
script->script.first_early_binding_opline = (uint32_t)-1;
SHM_PROTECT();
HANDLE_UNBLOCK_INTERRUPTIONS();
- zend_string_release(filename);
-
ZEND_ASSERT(ZCSG(preload_script)->arena_size == 0);
preload_load();
}
if (op_array->filename) {
- /* do not free! PHP has centralized filename storage, compiler will free it */
- zend_accel_memdup_string(op_array->filename);
+ zend_accel_store_string(op_array->filename);
}
if (op_array->arg_info) {
HT_FLAGS(&ce->constants_table) &= (HASH_FLAG_UNINITIALIZED | HASH_FLAG_STATIC_KEYS);
if (ce->info.user.filename) {
- /* do not free! PHP has centralized filename storage, compiler will free it */
- zend_accel_memdup_string(ce->info.user.filename);
+ zend_accel_store_string(ce->info.user.filename);
}
if (ce->info.user.doc_comment) {
if (ZCG(accel_directives).save_comments) {