From cd56395d4779582506b35c11e6dcd415112113d9 Mon Sep 17 00:00:00 2001 From: Tyson Andre Date: Sun, 19 Apr 2020 11:53:36 -0400 Subject: [PATCH] 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: ad8652818a5 ``` // 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 --- Zend/zend_vm_def.h | 4 ++-- Zend/zend_vm_execute.h | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 0797322a86..6a4719b3dd 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -8348,7 +8348,6 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(187, ZEND_SWITCH_LONG, CONST|TMPVARCV, CONST, JM HashTable *jumptable; op = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); - jumptable = Z_ARRVAL_P(GET_OP2_ZVAL_PTR(BP_VAR_R)); if (Z_TYPE_P(op) != IS_LONG) { ZVAL_DEREF(op); @@ -8358,6 +8357,7 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(187, ZEND_SWITCH_LONG, CONST|TMPVARCV, CONST, JM } } + jumptable = Z_ARRVAL_P(GET_OP2_ZVAL_PTR(BP_VAR_R)); jump_zv = zend_hash_index_find(jumptable, Z_LVAL_P(op)); if (jump_zv != NULL) { 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, HashTable *jumptable; op = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); - jumptable = Z_ARRVAL_P(GET_OP2_ZVAL_PTR(BP_VAR_R)); if (Z_TYPE_P(op) != IS_STRING) { if (OP1_TYPE == IS_CONST) { @@ -8391,6 +8390,7 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(188, ZEND_SWITCH_STRING, CONST|TMPVARCV, CONST, } } + jumptable = Z_ARRVAL_P(GET_OP2_ZVAL_PTR(BP_VAR_R)); jump_zv = zend_hash_find_ex(jumptable, Z_STR_P(op), OP1_TYPE == IS_CONST); if (jump_zv != NULL) { ZEND_VM_SET_RELATIVE_OPCODE(opline, Z_LVAL_P(jump_zv)); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 33e97f2b04..346dbec656 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -6454,7 +6454,6 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_LONG_SPEC_ HashTable *jumptable; op = RT_CONSTANT(opline, opline->op1); - jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); if (Z_TYPE_P(op) != IS_LONG) { ZVAL_DEREF(op); @@ -6464,6 +6463,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_LONG_SPEC_ } } + jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); jump_zv = zend_hash_index_find(jumptable, Z_LVAL_P(op)); if (jump_zv != NULL) { 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 HashTable *jumptable; op = RT_CONSTANT(opline, opline->op1); - jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); if (Z_TYPE_P(op) != IS_STRING) { if (IS_CONST == IS_CONST) { @@ -6497,6 +6496,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_STRING_SPE } } + jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); jump_zv = zend_hash_find_ex(jumptable, Z_STR_P(op), IS_CONST == IS_CONST); if (jump_zv != NULL) { 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 HashTable *jumptable; op = EX_VAR(opline->op1.var); - jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); if (Z_TYPE_P(op) != IS_LONG) { ZVAL_DEREF(op); @@ -11326,6 +11325,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONS } } + jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); jump_zv = zend_hash_index_find(jumptable, Z_LVAL_P(op)); if (jump_zv != NULL) { 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 HashTable *jumptable; op = EX_VAR(opline->op1.var); - jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); if (Z_TYPE_P(op) != IS_STRING) { 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 } } + jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); jump_zv = zend_hash_find_ex(jumptable, Z_STR_P(op), (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST); if (jump_zv != NULL) { ZEND_VM_SET_RELATIVE_OPCODE(opline, Z_LVAL_P(jump_zv)); -- 2.40.0