Skip to content

Commit f484801

Browse files
committed
Reduced amount of code generated for interrupt handling.
Improved ZEND_VM_INTERRUPT_CHECK() placement (always perform checks after opcode handler completion, when instruction pointer value is alredy changed to the next opcode).
1 parent 538d452 commit f484801

File tree

5 files changed

+44
-41
lines changed

5 files changed

+44
-41
lines changed

Zend/zend_execute.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2101,9 +2101,15 @@ void zend_free_compiled_variables(zend_execute_data *execute_data) /* {{{ */
21012101
/* }}} */
21022102

21032103
#ifdef ZEND_WIN32
2104+
static zend_never_inline ZEND_COLD ZEND_NORETURN void ZEND_FASTCALL zend_interrupt(void) /* {{{ */
2105+
{
2106+
zend_timeout(0);
2107+
}
2108+
/* }}} */
2109+
21042110
# define ZEND_VM_INTERRUPT_CHECK() do { \
2105-
if (EG(timed_out)) { \
2106-
zend_timeout(0); \
2111+
if (UNEXPECTED(EG(timed_out))) { \
2112+
zend_interrupt(); \
21072113
} \
21082114
} while (0)
21092115
#else
@@ -2198,7 +2204,6 @@ static zend_always_inline void i_init_func_execute_data(zend_execute_data *execu
21982204
EX_LOAD_LITERALS(op_array);
21992205

22002206
EG(current_execute_data) = execute_data;
2201-
ZEND_VM_INTERRUPT_CHECK();
22022207
}
22032208
/* }}} */
22042209

@@ -2235,7 +2240,6 @@ static zend_always_inline void i_init_code_execute_data(zend_execute_data *execu
22352240
EX_LOAD_LITERALS(op_array);
22362241

22372242
EG(current_execute_data) = execute_data;
2238-
ZEND_VM_INTERRUPT_CHECK();
22392243
}
22402244
/* }}} */
22412245

@@ -2326,7 +2330,6 @@ static zend_always_inline void i_init_execute_data(zend_execute_data *execute_da
23262330
EX_LOAD_LITERALS(op_array);
23272331

23282332
EG(current_execute_data) = execute_data;
2329-
ZEND_VM_INTERRUPT_CHECK();
23302333
}
23312334
/* }}} */
23322335

Zend/zend_vm_def.h

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3577,8 +3577,8 @@ ZEND_VM_HANDLER(129, ZEND_DO_ICALL, ANY, ANY, SPEC(RETVAL))
35773577
HANDLE_EXCEPTION();
35783578
}
35793579

3580-
ZEND_VM_INTERRUPT_CHECK();
3581-
ZEND_VM_NEXT_OPCODE();
3580+
ZEND_VM_SET_OPCODE(opline + 1);
3581+
ZEND_VM_CONTINUE();
35823582
}
35833583

35843584
ZEND_VM_HANDLER(130, ZEND_DO_UCALL, ANY, ANY, SPEC(RETVAL))
@@ -3694,8 +3694,8 @@ ZEND_VM_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL))
36943694
}
36953695
HANDLE_EXCEPTION();
36963696
}
3697-
ZEND_VM_INTERRUPT_CHECK();
3698-
ZEND_VM_NEXT_OPCODE();
3697+
ZEND_VM_SET_OPCODE(opline + 1);
3698+
ZEND_VM_CONTINUE();
36993699
}
37003700

37013701
ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL))
@@ -3854,8 +3854,8 @@ ZEND_VM_C_LABEL(fcall_end):
38543854
HANDLE_EXCEPTION();
38553855
}
38563856

3857-
ZEND_VM_INTERRUPT_CHECK();
3858-
ZEND_VM_NEXT_OPCODE();
3857+
ZEND_VM_SET_OPCODE(opline + 1);
3858+
ZEND_VM_CONTINUE();
38593859
}
38603860

38613861
ZEND_VM_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV, UNUSED)
@@ -5405,8 +5405,8 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMPVAR|CV, ANY, EVAL)
54055405
} else if (RETURN_VALUE_USED(opline)) {
54065406
ZVAL_FALSE(EX_VAR(opline->result.var));
54075407
}
5408-
ZEND_VM_INTERRUPT_CHECK();
5409-
ZEND_VM_NEXT_OPCODE();
5408+
ZEND_VM_SET_OPCODE(opline + 1);
5409+
ZEND_VM_CONTINUE();
54105410
}
54115411

54125412
ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMPVAR|CV, UNUSED, VAR_FETCH|ISSET)
@@ -7078,8 +7078,6 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
70787078
uint32_t catch_op_num = 0, finally_op_num = 0, finally_op_end = 0;
70797079
int in_finally = 0;
70807080

7081-
ZEND_VM_INTERRUPT_CHECK();
7082-
70837081
{
70847082
const zend_op *exc_opline = EG(opline_before_exception);
70857083
if ((exc_opline->opcode == ZEND_FREE || exc_opline->opcode == ZEND_FE_FREE)
@@ -7539,10 +7537,10 @@ ZEND_VM_HANDLER(163, ZEND_FAST_RET, ANY, TRY_CATCH, FAST_RET)
75397537

75407538
if (fast_call->u2.lineno != (uint32_t)-1) {
75417539
const zend_op *fast_ret = EX(func)->op_array.opcodes + fast_call->u2.lineno;
7542-
ZEND_VM_SET_OPCODE(fast_ret + 1);
75437540
if (fast_ret->extended_value & ZEND_FAST_CALL_FROM_FINALLY) {
75447541
fast_call->u2.lineno = EX(func)->op_array.try_catch_array[fast_ret->op2.num].finally_op - 2;
75457542
}
7543+
ZEND_VM_SET_OPCODE(fast_ret + 1);
75467544
ZEND_VM_CONTINUE();
75477545
} else {
75487546
/* special case for unhandled exceptions */

Zend/zend_vm_execute.h

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ typedef ZEND_OPCODE_HANDLER_RET (ZEND_FASTCALL *opcode_handler_t) (ZEND_OPCODE_H
387387
#define HANDLE_EXCEPTION() LOAD_OPLINE(); ZEND_VM_CONTINUE()
388388
#define HANDLE_EXCEPTION_LEAVE() LOAD_OPLINE(); ZEND_VM_LEAVE()
389389
#if defined(ZEND_VM_FP_GLOBAL_REG)
390-
# define ZEND_VM_ENTER() execute_data = EG(current_execute_data); LOAD_OPLINE(); ZEND_VM_CONTINUE()
390+
# define ZEND_VM_ENTER() execute_data = EG(current_execute_data); LOAD_OPLINE(); ZEND_VM_INTERRUPT_CHECK(); ZEND_VM_CONTINUE()
391391
# define ZEND_VM_LEAVE() ZEND_VM_CONTINUE()
392392
#elif defined(ZEND_VM_IP_GLOBAL_REG)
393393
# define ZEND_VM_ENTER() opline = EG(current_execute_data)->opline; return 1
@@ -415,6 +415,7 @@ ZEND_API void execute_ex(zend_execute_data *ex)
415415

416416

417417
LOAD_OPLINE();
418+
ZEND_VM_INTERRUPT_CHECK();
418419

419420
while (1) {
420421
#if !defined(ZEND_VM_FP_GLOBAL_REG) || !defined(ZEND_VM_IP_GLOBAL_REG)
@@ -435,6 +436,7 @@ ZEND_API void execute_ex(zend_execute_data *ex)
435436
#else
436437
if (EXPECTED(ret > 0)) {
437438
execute_data = EG(current_execute_data);
439+
ZEND_VM_INTERRUPT_CHECK();
438440
} else {
439441
# ifdef ZEND_VM_IP_GLOBAL_REG
440442
opline = orig_opline;
@@ -638,8 +640,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HA
638640
HANDLE_EXCEPTION();
639641
}
640642

641-
ZEND_VM_INTERRUPT_CHECK();
642-
ZEND_VM_NEXT_OPCODE();
643+
ZEND_VM_SET_OPCODE(opline + 1);
644+
ZEND_VM_CONTINUE();
643645
}
644646

645647
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -685,8 +687,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETVAL_USED_HAND
685687
HANDLE_EXCEPTION();
686688
}
687689

688-
ZEND_VM_INTERRUPT_CHECK();
689-
ZEND_VM_NEXT_OPCODE();
690+
ZEND_VM_SET_OPCODE(opline + 1);
691+
ZEND_VM_CONTINUE();
690692
}
691693

692694
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_UCALL_SPEC_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -826,8 +828,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_U
826828
}
827829
HANDLE_EXCEPTION();
828830
}
829-
ZEND_VM_INTERRUPT_CHECK();
830-
ZEND_VM_NEXT_OPCODE();
831+
ZEND_VM_SET_OPCODE(opline + 1);
832+
ZEND_VM_CONTINUE();
831833
}
832834

833835
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -919,8 +921,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_U
919921
}
920922
HANDLE_EXCEPTION();
921923
}
922-
ZEND_VM_INTERRUPT_CHECK();
923-
ZEND_VM_NEXT_OPCODE();
924+
ZEND_VM_SET_OPCODE(opline + 1);
925+
ZEND_VM_CONTINUE();
924926
}
925927

926928
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -1079,8 +1081,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HA
10791081
HANDLE_EXCEPTION();
10801082
}
10811083

1082-
ZEND_VM_INTERRUPT_CHECK();
1083-
ZEND_VM_NEXT_OPCODE();
1084+
ZEND_VM_SET_OPCODE(opline + 1);
1085+
ZEND_VM_CONTINUE();
10841086
}
10851087

10861088
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -1239,8 +1241,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_USED_HAND
12391241
HANDLE_EXCEPTION();
12401242
}
12411243

1242-
ZEND_VM_INTERRUPT_CHECK();
1243-
ZEND_VM_NEXT_OPCODE();
1244+
ZEND_VM_SET_OPCODE(opline + 1);
1245+
ZEND_VM_CONTINUE();
12441246
}
12451247

12461248
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_UNPACK_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -1725,8 +1727,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(
17251727
uint32_t catch_op_num = 0, finally_op_num = 0, finally_op_end = 0;
17261728
int in_finally = 0;
17271729

1728-
ZEND_VM_INTERRUPT_CHECK();
1729-
17301730
{
17311731
const zend_op *exc_opline = EG(opline_before_exception);
17321732
if ((exc_opline->opcode == ZEND_FREE || exc_opline->opcode == ZEND_FE_FREE)
@@ -1876,10 +1876,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_RET_SPEC_HANDLER(ZEND_OPC
18761876

18771877
if (fast_call->u2.lineno != (uint32_t)-1) {
18781878
const zend_op *fast_ret = EX(func)->op_array.opcodes + fast_call->u2.lineno;
1879-
ZEND_VM_SET_OPCODE(fast_ret + 1);
18801879
if (fast_ret->extended_value & ZEND_FAST_CALL_FROM_FINALLY) {
18811880
fast_call->u2.lineno = EX(func)->op_array.try_catch_array[fast_ret->op2.num].finally_op - 2;
18821881
}
1882+
ZEND_VM_SET_OPCODE(fast_ret + 1);
18831883
ZEND_VM_CONTINUE();
18841884
} else {
18851885
/* special case for unhandled exceptions */
@@ -3457,8 +3457,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HAN
34573457
} else if (RETURN_VALUE_USED(opline)) {
34583458
ZVAL_FALSE(EX_VAR(opline->result.var));
34593459
}
3460-
ZEND_VM_INTERRUPT_CHECK();
3461-
ZEND_VM_NEXT_OPCODE();
3460+
ZEND_VM_SET_OPCODE(opline + 1);
3461+
ZEND_VM_CONTINUE();
34623462
}
34633463

34643464
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -35529,8 +35529,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLE
3552935529
} else if (RETURN_VALUE_USED(opline)) {
3553035530
ZVAL_FALSE(EX_VAR(opline->result.var));
3553135531
}
35532-
ZEND_VM_INTERRUPT_CHECK();
35533-
ZEND_VM_NEXT_OPCODE();
35532+
ZEND_VM_SET_OPCODE(opline + 1);
35533+
ZEND_VM_CONTINUE();
3553435534
}
3553535535

3553635536
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -50276,8 +50276,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_HA
5027650276
} else if (RETURN_VALUE_USED(opline)) {
5027750277
ZVAL_FALSE(EX_VAR(opline->result.var));
5027850278
}
50279-
ZEND_VM_INTERRUPT_CHECK();
50280-
ZEND_VM_NEXT_OPCODE();
50279+
ZEND_VM_SET_OPCODE(opline + 1);
50280+
ZEND_VM_CONTINUE();
5028150281
}
5028250282

5028350283
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_EXIT_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)

Zend/zend_vm_execute.skl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ ZEND_API void {%EXECUTOR_NAME%}_ex(zend_execute_data *ex)
99
{%INTERNAL_LABELS%}
1010

1111
LOAD_OPLINE();
12+
ZEND_VM_INTERRUPT_CHECK();
1213

1314
while (1) {
1415
{%ZEND_VM_CONTINUE_LABEL%}

Zend/zend_vm_gen.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1575,7 +1575,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
15751575
out($f,"#define HANDLE_EXCEPTION() LOAD_OPLINE(); ZEND_VM_CONTINUE()\n");
15761576
out($f,"#define HANDLE_EXCEPTION_LEAVE() LOAD_OPLINE(); ZEND_VM_LEAVE()\n");
15771577
out($f,"#if defined(ZEND_VM_FP_GLOBAL_REG)\n");
1578-
out($f,"# define ZEND_VM_ENTER() execute_data = EG(current_execute_data); LOAD_OPLINE(); ZEND_VM_CONTINUE()\n");
1578+
out($f,"# define ZEND_VM_ENTER() execute_data = EG(current_execute_data); LOAD_OPLINE(); ZEND_VM_INTERRUPT_CHECK(); ZEND_VM_CONTINUE()\n");
15791579
out($f,"# define ZEND_VM_LEAVE() ZEND_VM_CONTINUE()\n");
15801580
out($f,"#elif defined(ZEND_VM_IP_GLOBAL_REG)\n");
15811581
out($f,"# define ZEND_VM_ENTER() opline = EG(current_execute_data)->opline; return 1\n");
@@ -1611,7 +1611,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
16111611
out($f,"#define HANDLE_EXCEPTION_LEAVE() LOAD_OPLINE(); ZEND_VM_LEAVE()\n");
16121612
out($f,"#define ZEND_VM_CONTINUE() goto zend_vm_continue\n");
16131613
out($f,"#define ZEND_VM_RETURN() return\n");
1614-
out($f,"#define ZEND_VM_ENTER() execute_data = EG(current_execute_data); LOAD_OPLINE(); ZEND_VM_CONTINUE()\n");
1614+
out($f,"#define ZEND_VM_ENTER() execute_data = EG(current_execute_data); LOAD_OPLINE(); ZEND_VM_INTERRUPT_CHECK(); ZEND_VM_CONTINUE()\n");
16151615
out($f,"#define ZEND_VM_LEAVE() ZEND_VM_CONTINUE()\n");
16161616
out($f,"#define ZEND_VM_DISPATCH(opcode, opline) dispatch_handler = zend_vm_get_opcode_handler(opcode, opline); goto zend_vm_dispatch;\n");
16171617
out($f,"\n");
@@ -1645,7 +1645,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
16451645
}
16461646
out($f,"#define ZEND_VM_CONTINUE() goto *(void**)(OPLINE->handler)\n");
16471647
out($f,"#define ZEND_VM_RETURN() return\n");
1648-
out($f,"#define ZEND_VM_ENTER() execute_data = EG(current_execute_data); LOAD_OPLINE(); ZEND_VM_CONTINUE()\n");
1648+
out($f,"#define ZEND_VM_ENTER() execute_data = EG(current_execute_data); LOAD_OPLINE(); ZEND_VM_INTERRUPT_CHECK(); ZEND_VM_CONTINUE()\n");
16491649
out($f,"#define ZEND_VM_LEAVE() ZEND_VM_CONTINUE()\n");
16501650
out($f,"#define ZEND_VM_DISPATCH(opcode, opline) goto *(void**)(zend_vm_get_opcode_handler(opcode, opline));\n");
16511651
out($f,"\n");
@@ -1747,6 +1747,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
17471747
"#else\n" .
17481748
$m[1]."if (EXPECTED(ret > 0)) {\n" .
17491749
$m[1]."\texecute_data = EG(current_execute_data);\n".
1750+
$m[1]."\tZEND_VM_INTERRUPT_CHECK();\n".
17501751
$m[1]."} else {\n" .
17511752
"# ifdef ZEND_VM_IP_GLOBAL_REG\n" .
17521753
$m[1]."\topline = orig_opline;\n" .

0 commit comments

Comments
 (0)