Skip to content

Commit cd56395

Browse files
committed
Speed up ZEND_SWITCH_STRING/ZEND_SWITCH_LONG for wrong type
This has the minor benefit of avoiding loading the address of the jump table when the expression for the switch isn't a string/long. gcc doesn't seem to optimize that. The previous function body is the original implementation: ad86528 ``` // Before: 0.267s, after: 0.265s function test_switch($x) { for ($i = 0; $i < 10000000; $i++) { switch ($x) { case 'a': case 'b': echo "i=$i\n"; } } } test_switch(null); ``` Closes GH-5419
1 parent 928b25c commit cd56395

File tree

2 files changed

+6
-6
lines changed

2 files changed

+6
-6
lines changed

Zend/zend_vm_def.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8348,7 +8348,6 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(187, ZEND_SWITCH_LONG, CONST|TMPVARCV, CONST, JM
83488348
HashTable *jumptable;
83498349

83508350
op = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
8351-
jumptable = Z_ARRVAL_P(GET_OP2_ZVAL_PTR(BP_VAR_R));
83528351

83538352
if (Z_TYPE_P(op) != IS_LONG) {
83548353
ZVAL_DEREF(op);
@@ -8358,6 +8357,7 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(187, ZEND_SWITCH_LONG, CONST|TMPVARCV, CONST, JM
83588357
}
83598358
}
83608359

8360+
jumptable = Z_ARRVAL_P(GET_OP2_ZVAL_PTR(BP_VAR_R));
83618361
jump_zv = zend_hash_index_find(jumptable, Z_LVAL_P(op));
83628362
if (jump_zv != NULL) {
83638363
ZEND_VM_SET_RELATIVE_OPCODE(opline, Z_LVAL_P(jump_zv));
@@ -8376,7 +8376,6 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(188, ZEND_SWITCH_STRING, CONST|TMPVARCV, CONST,
83768376
HashTable *jumptable;
83778377

83788378
op = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
8379-
jumptable = Z_ARRVAL_P(GET_OP2_ZVAL_PTR(BP_VAR_R));
83808379

83818380
if (Z_TYPE_P(op) != IS_STRING) {
83828381
if (OP1_TYPE == IS_CONST) {
@@ -8391,6 +8390,7 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(188, ZEND_SWITCH_STRING, CONST|TMPVARCV, CONST,
83918390
}
83928391
}
83938392

8393+
jumptable = Z_ARRVAL_P(GET_OP2_ZVAL_PTR(BP_VAR_R));
83948394
jump_zv = zend_hash_find_ex(jumptable, Z_STR_P(op), OP1_TYPE == IS_CONST);
83958395
if (jump_zv != NULL) {
83968396
ZEND_VM_SET_RELATIVE_OPCODE(opline, Z_LVAL_P(jump_zv));

Zend/zend_vm_execute.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6454,7 +6454,6 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_LONG_SPEC_
64546454
HashTable *jumptable;
64556455

64566456
op = RT_CONSTANT(opline, opline->op1);
6457-
jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2));
64586457

64596458
if (Z_TYPE_P(op) != IS_LONG) {
64606459
ZVAL_DEREF(op);
@@ -6464,6 +6463,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_LONG_SPEC_
64646463
}
64656464
}
64666465

6466+
jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2));
64676467
jump_zv = zend_hash_index_find(jumptable, Z_LVAL_P(op));
64686468
if (jump_zv != NULL) {
64696469
ZEND_VM_SET_RELATIVE_OPCODE(opline, Z_LVAL_P(jump_zv));
@@ -6482,7 +6482,6 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_STRING_SPE
64826482
HashTable *jumptable;
64836483

64846484
op = RT_CONSTANT(opline, opline->op1);
6485-
jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2));
64866485

64876486
if (Z_TYPE_P(op) != IS_STRING) {
64886487
if (IS_CONST == IS_CONST) {
@@ -6497,6 +6496,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_STRING_SPE
64976496
}
64986497
}
64996498

6499+
jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2));
65006500
jump_zv = zend_hash_find_ex(jumptable, Z_STR_P(op), IS_CONST == IS_CONST);
65016501
if (jump_zv != NULL) {
65026502
ZEND_VM_SET_RELATIVE_OPCODE(opline, Z_LVAL_P(jump_zv));
@@ -11316,7 +11316,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONS
1131611316
HashTable *jumptable;
1131711317

1131811318
op = EX_VAR(opline->op1.var);
11319-
jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2));
1132011319

1132111320
if (Z_TYPE_P(op) != IS_LONG) {
1132211321
ZVAL_DEREF(op);
@@ -11326,6 +11325,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONS
1132611325
}
1132711326
}
1132811327

11328+
jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2));
1132911329
jump_zv = zend_hash_index_find(jumptable, Z_LVAL_P(op));
1133011330
if (jump_zv != NULL) {
1133111331
ZEND_VM_SET_RELATIVE_OPCODE(opline, Z_LVAL_P(jump_zv));
@@ -11344,7 +11344,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_STRING_SPEC_TMPVARCV_CO
1134411344
HashTable *jumptable;
1134511345

1134611346
op = EX_VAR(opline->op1.var);
11347-
jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2));
1134811347

1134911348
if (Z_TYPE_P(op) != IS_STRING) {
1135011349
if ((IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) {
@@ -11359,6 +11358,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_STRING_SPEC_TMPVARCV_CO
1135911358
}
1136011359
}
1136111360

11361+
jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2));
1136211362
jump_zv = zend_hash_find_ex(jumptable, Z_STR_P(op), (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST);
1136311363
if (jump_zv != NULL) {
1136411364
ZEND_VM_SET_RELATIVE_OPCODE(opline, Z_LVAL_P(jump_zv));

0 commit comments

Comments
 (0)