Skip to content

Commit 192ea91

Browse files
committed
Avoid useless symbol table reattaching on retutn from an included op_array
1 parent 67bb792 commit 192ea91

File tree

3 files changed

+67
-42
lines changed

3 files changed

+67
-42
lines changed

Zend/zend_compile.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,7 @@ struct _zend_execute_data {
556556
/* to prevent optimization in RETURN handler and */
557557
/* keep all local variables for "fcall_end" handler */
558558
#define ZEND_CALL_JIT_RESERVED (1 << 29) /* reserved for tracing JIT */
559+
#define ZEND_CALL_NEEDS_REATTACH (1 << 30)
559560
#define ZEND_CALL_SEND_ARG_BY_REF (1u << 31)
560561

561562
#define ZEND_CALL_NESTED_FUNCTION (ZEND_CALL_FUNCTION | ZEND_CALL_NESTED)

Zend/zend_vm_def.h

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2865,19 +2865,21 @@ ZEND_VM_HOT_HELPER(zend_leave_helper, ANY, ANY)
28652865
} else if (EXPECTED((call_info & ZEND_CALL_TOP) == 0)) {
28662866
if (EX(func)->op_array.last_var > 0) {
28672867
zend_detach_symbol_table(execute_data);
2868+
call_info |= ZEND_CALL_NEEDS_REATTACH;
28682869
}
28692870
zend_destroy_static_vars(&EX(func)->op_array);
28702871
destroy_op_array(&EX(func)->op_array);
28712872
efree_size(EX(func), sizeof(zend_op_array));
2872-
#ifdef ZEND_PREFER_RELOAD
2873-
call_info = EX_CALL_INFO();
2874-
#endif
28752873
old_execute_data = execute_data;
28762874
execute_data = EG(current_execute_data) = EX(prev_execute_data);
28772875
zend_vm_stack_free_call_frame_ex(call_info, old_execute_data);
28782876

2879-
if (EX(func)->op_array.last_var > 0) {
2880-
zend_attach_symbol_table(execute_data);
2877+
if (call_info & ZEND_CALL_NEEDS_REATTACH) {
2878+
if (EX(func)->op_array.last_var > 0) {
2879+
zend_attach_symbol_table(execute_data);
2880+
} else {
2881+
ZEND_ADD_CALL_FLAG(execute_data, ZEND_CALL_NEEDS_REATTACH);
2882+
}
28812883
}
28822884
if (UNEXPECTED(EG(exception) != NULL)) {
28832885
zend_rethrow_exception(execute_data);
@@ -2911,17 +2913,23 @@ ZEND_VM_HOT_HELPER(zend_leave_helper, ANY, ANY)
29112913

29122914
if (EX(func)->op_array.last_var > 0) {
29132915
zend_detach_symbol_table(execute_data);
2914-
}
2915-
old_execute_data = EX(prev_execute_data);
2916-
while (old_execute_data) {
2917-
if (old_execute_data->func && (ZEND_CALL_INFO(old_execute_data) & ZEND_CALL_HAS_SYMBOL_TABLE)) {
2918-
if (old_execute_data->symbol_table == symbol_table
2919-
&& old_execute_data->func->op_array.last_var > 0) {
2920-
zend_attach_symbol_table(old_execute_data);
2916+
call_info |= ZEND_CALL_NEEDS_REATTACH;
2917+
}
2918+
if (call_info & ZEND_CALL_NEEDS_REATTACH) {
2919+
old_execute_data = EX(prev_execute_data);
2920+
while (old_execute_data) {
2921+
if (old_execute_data->func && (ZEND_CALL_INFO(old_execute_data) & ZEND_CALL_HAS_SYMBOL_TABLE)) {
2922+
if (old_execute_data->symbol_table == symbol_table) {
2923+
if (old_execute_data->func->op_array.last_var > 0) {
2924+
zend_attach_symbol_table(old_execute_data);
2925+
} else {
2926+
ZEND_ADD_CALL_FLAG(old_execute_data, ZEND_CALL_NEEDS_REATTACH);
2927+
}
2928+
}
2929+
break;
29212930
}
2922-
break;
2931+
old_execute_data = old_execute_data->prev_execute_data;
29232932
}
2924-
old_execute_data = old_execute_data->prev_execute_data;
29252933
}
29262934
EG(current_execute_data) = EX(prev_execute_data);
29272935
ZEND_VM_RETURN();

Zend/zend_vm_execute.h

Lines changed: 44 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1147,19 +1147,21 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper
11471147
} else if (EXPECTED((call_info & ZEND_CALL_TOP) == 0)) {
11481148
if (EX(func)->op_array.last_var > 0) {
11491149
zend_detach_symbol_table(execute_data);
1150+
call_info |= ZEND_CALL_NEEDS_REATTACH;
11501151
}
11511152
zend_destroy_static_vars(&EX(func)->op_array);
11521153
destroy_op_array(&EX(func)->op_array);
11531154
efree_size(EX(func), sizeof(zend_op_array));
1154-
#ifdef ZEND_PREFER_RELOAD
1155-
call_info = EX_CALL_INFO();
1156-
#endif
11571155
old_execute_data = execute_data;
11581156
execute_data = EG(current_execute_data) = EX(prev_execute_data);
11591157
zend_vm_stack_free_call_frame_ex(call_info, old_execute_data);
11601158

1161-
if (EX(func)->op_array.last_var > 0) {
1162-
zend_attach_symbol_table(execute_data);
1159+
if (call_info & ZEND_CALL_NEEDS_REATTACH) {
1160+
if (EX(func)->op_array.last_var > 0) {
1161+
zend_attach_symbol_table(execute_data);
1162+
} else {
1163+
ZEND_ADD_CALL_FLAG(execute_data, ZEND_CALL_NEEDS_REATTACH);
1164+
}
11631165
}
11641166
if (UNEXPECTED(EG(exception) != NULL)) {
11651167
zend_rethrow_exception(execute_data);
@@ -1193,17 +1195,23 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper
11931195

11941196
if (EX(func)->op_array.last_var > 0) {
11951197
zend_detach_symbol_table(execute_data);
1196-
}
1197-
old_execute_data = EX(prev_execute_data);
1198-
while (old_execute_data) {
1199-
if (old_execute_data->func && (ZEND_CALL_INFO(old_execute_data) & ZEND_CALL_HAS_SYMBOL_TABLE)) {
1200-
if (old_execute_data->symbol_table == symbol_table
1201-
&& old_execute_data->func->op_array.last_var > 0) {
1202-
zend_attach_symbol_table(old_execute_data);
1198+
call_info |= ZEND_CALL_NEEDS_REATTACH;
1199+
}
1200+
if (call_info & ZEND_CALL_NEEDS_REATTACH) {
1201+
old_execute_data = EX(prev_execute_data);
1202+
while (old_execute_data) {
1203+
if (old_execute_data->func && (ZEND_CALL_INFO(old_execute_data) & ZEND_CALL_HAS_SYMBOL_TABLE)) {
1204+
if (old_execute_data->symbol_table == symbol_table) {
1205+
if (old_execute_data->func->op_array.last_var > 0) {
1206+
zend_attach_symbol_table(old_execute_data);
1207+
} else {
1208+
ZEND_ADD_CALL_FLAG(old_execute_data, ZEND_CALL_NEEDS_REATTACH);
1209+
}
1210+
}
1211+
break;
12031212
}
1204-
break;
1213+
old_execute_data = old_execute_data->prev_execute_data;
12051214
}
1206-
old_execute_data = old_execute_data->prev_execute_data;
12071215
}
12081216
EG(current_execute_data) = EX(prev_execute_data);
12091217
ZEND_VM_RETURN();
@@ -55455,19 +55463,21 @@ ZEND_API void execute_ex(zend_execute_data *ex)
5545555463
} else if (EXPECTED((call_info & ZEND_CALL_TOP) == 0)) {
5545655464
if (EX(func)->op_array.last_var > 0) {
5545755465
zend_detach_symbol_table(execute_data);
55466+
call_info |= ZEND_CALL_NEEDS_REATTACH;
5545855467
}
5545955468
zend_destroy_static_vars(&EX(func)->op_array);
5546055469
destroy_op_array(&EX(func)->op_array);
5546155470
efree_size(EX(func), sizeof(zend_op_array));
55462-
#ifdef ZEND_PREFER_RELOAD
55463-
call_info = EX_CALL_INFO();
55464-
#endif
5546555471
old_execute_data = execute_data;
5546655472
execute_data = EG(current_execute_data) = EX(prev_execute_data);
5546755473
zend_vm_stack_free_call_frame_ex(call_info, old_execute_data);
5546855474

55469-
if (EX(func)->op_array.last_var > 0) {
55470-
zend_attach_symbol_table(execute_data);
55475+
if (call_info & ZEND_CALL_NEEDS_REATTACH) {
55476+
if (EX(func)->op_array.last_var > 0) {
55477+
zend_attach_symbol_table(execute_data);
55478+
} else {
55479+
ZEND_ADD_CALL_FLAG(execute_data, ZEND_CALL_NEEDS_REATTACH);
55480+
}
5547155481
}
5547255482
if (UNEXPECTED(EG(exception) != NULL)) {
5547355483
zend_rethrow_exception(execute_data);
@@ -55501,17 +55511,23 @@ ZEND_API void execute_ex(zend_execute_data *ex)
5550155511

5550255512
if (EX(func)->op_array.last_var > 0) {
5550355513
zend_detach_symbol_table(execute_data);
55504-
}
55505-
old_execute_data = EX(prev_execute_data);
55506-
while (old_execute_data) {
55507-
if (old_execute_data->func && (ZEND_CALL_INFO(old_execute_data) & ZEND_CALL_HAS_SYMBOL_TABLE)) {
55508-
if (old_execute_data->symbol_table == symbol_table
55509-
&& old_execute_data->func->op_array.last_var > 0) {
55510-
zend_attach_symbol_table(old_execute_data);
55514+
call_info |= ZEND_CALL_NEEDS_REATTACH;
55515+
}
55516+
if (call_info & ZEND_CALL_NEEDS_REATTACH) {
55517+
old_execute_data = EX(prev_execute_data);
55518+
while (old_execute_data) {
55519+
if (old_execute_data->func && (ZEND_CALL_INFO(old_execute_data) & ZEND_CALL_HAS_SYMBOL_TABLE)) {
55520+
if (old_execute_data->symbol_table == symbol_table) {
55521+
if (old_execute_data->func->op_array.last_var > 0) {
55522+
zend_attach_symbol_table(old_execute_data);
55523+
} else {
55524+
ZEND_ADD_CALL_FLAG(old_execute_data, ZEND_CALL_NEEDS_REATTACH);
55525+
}
55526+
}
55527+
break;
5551155528
}
55512-
break;
55529+
old_execute_data = old_execute_data->prev_execute_data;
5551355530
}
55514-
old_execute_data = old_execute_data->prev_execute_data;
5551555531
}
5551655532
EG(current_execute_data) = EX(prev_execute_data);
5551755533
ZEND_VM_RETURN();

0 commit comments

Comments
 (0)