@@ -4947,21 +4947,26 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
4947
4947
}
4948
4948
4949
4949
if (op2_info & MAY_BE_LONG) {
4950
+ zend_bool op2_loaded = 0;
4951
+
4950
4952
if (op2_info & ((MAY_BE_ANY|MAY_BE_UNDEF) - MAY_BE_LONG)) {
4951
4953
| // if (EXPECTED(Z_TYPE_P(dim) == IS_LONG))
4952
4954
| IF_NOT_ZVAL_TYPE op2_addr, IS_LONG, >3
4953
4955
}
4954
- if (type == BP_VAR_W || type == BP_VAR_RW ) {
4956
+ if (type == BP_VAR_W) {
4955
4957
| // hval = Z_LVAL_P(dim);
4956
4958
| GET_ZVAL_LVAL ZREG_FCARG2a, op2_addr
4959
+ op2_loaded = 1;
4957
4960
}
4958
- if (op1_info & MAY_BE_ARRAY_KEY_LONG) {
4961
+ if (( op1_info & MAY_BE_ARRAY_KEY_LONG) && (op1_info & MAY_BE_ARRAY_PACKED) ) {
4959
4962
if (Z_MODE(op2_addr) == IS_CONST_ZVAL) {
4960
4963
zend_long val = Z_LVAL_P(Z_ZV(op2_addr));
4961
4964
if (val >= 0 && val < HT_MAX_SIZE) {
4962
4965
| // ZEND_HASH_INDEX_FIND(ht, hval, retval, num_undef);
4963
- | test dword [FCARG1a + offsetof(zend_array, u.flags)], HASH_FLAG_PACKED
4964
- | jz >4 // HASH_FIND
4966
+ if (op1_info & MAY_BE_ARRAY_HASH) {
4967
+ | test dword [FCARG1a + offsetof(zend_array, u.flags)], HASH_FLAG_PACKED
4968
+ | jz >4 // HASH_FIND
4969
+ }
4965
4970
| // if (EXPECTED((zend_ulong)(_h) < (zend_ulong)(_ht)->nNumUsed))
4966
4971
|.if X64
4967
4972
| movsxd r0, dword [FCARG1a + offsetof(zend_array, nNumUsed)]
@@ -4998,13 +5003,16 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
4998
5003
}
4999
5004
}
5000
5005
} else {
5001
- if (type != BP_VAR_W && type != BP_VAR_RW ) {
5006
+ if (!op2_loaded ) {
5002
5007
| // hval = Z_LVAL_P(dim);
5003
5008
| GET_ZVAL_LVAL ZREG_FCARG2a, op2_addr
5009
+ op2_loaded = 1;
5004
5010
}
5005
5011
| // ZEND_HASH_INDEX_FIND(ht, hval, retval, num_undef);
5006
- | test dword [FCARG1a + offsetof(zend_array, u.flags)], HASH_FLAG_PACKED
5007
- | jz >4 // HASH_FIND
5012
+ if (op1_info & MAY_BE_ARRAY_HASH) {
5013
+ | test dword [FCARG1a + offsetof(zend_array, u.flags)], HASH_FLAG_PACKED
5014
+ | jz >4 // HASH_FIND
5015
+ }
5008
5016
| // if (EXPECTED((zend_ulong)(_h) < (zend_ulong)(_ht)->nNumUsed))
5009
5017
|.if X64
5010
5018
| movsxd r0, dword [FCARG1a + offsetof(zend_array, nNumUsed)]
@@ -5042,60 +5050,58 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
5042
5050
}
5043
5051
switch (type) {
5044
5052
case BP_JIT_IS:
5045
- if (op1_info & MAY_BE_ARRAY_KEY_LONG) {
5053
+ if (( op1_info & MAY_BE_ARRAY_KEY_LONG) && (op1_info & MAY_BE_ARRAY_HASH) ) {
5046
5054
|4:
5047
- }
5048
- if (Z_MODE(op2_addr) == IS_CONST_ZVAL) {
5049
- | // hval = Z_LVAL_P(dim);
5050
- | GET_ZVAL_LVAL ZREG_FCARG2a, op2_addr
5051
- }
5052
- | EXT_CALL _zend_hash_index_find, r0
5053
- | test r0, r0
5054
- if (not_found_exit_addr) {
5055
- | jz ¬_found_exit_addr
5055
+ if (!op2_loaded) {
5056
+ | // hval = Z_LVAL_P(dim);
5057
+ | GET_ZVAL_LVAL ZREG_FCARG2a, op2_addr
5058
+ }
5059
+ | EXT_CALL _zend_hash_index_find, r0
5060
+ | test r0, r0
5061
+ if (not_found_exit_addr) {
5062
+ | jz ¬_found_exit_addr
5063
+ } else {
5064
+ | jz >9 // NOT_FOUND
5065
+ }
5066
+ if (op2_info & MAY_BE_STRING) {
5067
+ | jmp >5
5068
+ }
5069
+ } else if (not_found_exit_addr) {
5070
+ | jmp ¬_found_exit_addr
5056
5071
} else {
5057
- | jz >9 // NOT_FOUND
5058
- }
5059
- if (op2_info & MAY_BE_STRING) {
5060
- | jmp >5
5072
+ | jmp >9 // NOT_FOUND
5061
5073
}
5062
5074
break;
5063
5075
case BP_VAR_R:
5064
5076
case BP_VAR_IS:
5065
5077
case BP_VAR_UNSET:
5066
- if (op1_info & MAY_BE_ARRAY_KEY_LONG) {
5067
- if (Z_MODE(op2_addr) == IS_CONST_ZVAL) {
5068
- zend_long val = Z_LVAL_P(Z_ZV(op2_addr));
5069
- if (val >= 0 && val < HT_MAX_SIZE) {
5070
- if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE && type == BP_VAR_R) {
5071
- | jmp &exit_addr
5072
- } else if (type == BP_VAR_IS && not_found_exit_addr) {
5073
- | jmp ¬_found_exit_addr
5074
- } else {
5075
- | jmp >2 // NOT_FOUND
5076
- }
5077
- }
5078
- } else if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE && type == BP_VAR_R) {
5078
+ if (!(op1_info & MAY_BE_ARRAY_KEY_LONG) ||
5079
+ !(op1_info & MAY_BE_ARRAY_HASH) ||
5080
+ Z_MODE(op2_addr) != IS_CONST_ZVAL ||
5081
+ (Z_LVAL_P(Z_ZV(op2_addr)) >= 0 && Z_LVAL_P(Z_ZV(op2_addr)) < HT_MAX_SIZE)) {
5082
+ if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE && type == BP_VAR_R) {
5079
5083
| jmp &exit_addr
5080
5084
} else if (type == BP_VAR_IS && not_found_exit_addr) {
5081
5085
| jmp ¬_found_exit_addr
5082
5086
} else {
5083
5087
| jmp >2 // NOT_FOUND
5084
5088
}
5085
- |4:
5086
5089
}
5087
- if (Z_MODE(op2_addr) == IS_CONST_ZVAL) {
5088
- | // hval = Z_LVAL_P(dim);
5089
- | GET_ZVAL_LVAL ZREG_FCARG2a, op2_addr
5090
- }
5091
- | EXT_CALL _zend_hash_index_find, r0
5092
- | test r0, r0
5093
- if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE && type == BP_VAR_R) {
5094
- | jz &exit_addr
5095
- } else if (type == BP_VAR_IS && not_found_exit_addr) {
5096
- | jz ¬_found_exit_addr
5097
- } else {
5098
- | jz >2 // NOT_FOUND
5090
+ if ((op1_info & MAY_BE_ARRAY_KEY_LONG) && (op1_info & MAY_BE_ARRAY_HASH)) {
5091
+ |4:
5092
+ if (!op2_loaded) {
5093
+ | // hval = Z_LVAL_P(dim);
5094
+ | GET_ZVAL_LVAL ZREG_FCARG2a, op2_addr
5095
+ }
5096
+ | EXT_CALL _zend_hash_index_find, r0
5097
+ | test r0, r0
5098
+ if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE && type == BP_VAR_R) {
5099
+ | jz &exit_addr
5100
+ } else if (type == BP_VAR_IS && not_found_exit_addr) {
5101
+ | jz ¬_found_exit_addr
5102
+ } else {
5103
+ | jz >2 // NOT_FOUND
5104
+ }
5099
5105
}
5100
5106
|.cold_code
5101
5107
|2:
@@ -5124,6 +5130,10 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
5124
5130
case BP_VAR_RW:
5125
5131
|2:
5126
5132
|4:
5133
+ if (!op2_loaded) {
5134
+ | // hval = Z_LVAL_P(dim);
5135
+ | GET_ZVAL_LVAL ZREG_FCARG2a, op2_addr
5136
+ }
5127
5137
| SAVE_VALID_OPLINE opline, r0
5128
5138
| EXT_CALL zend_jit_hash_index_lookup_rw, r0
5129
5139
| test r0, r0
0 commit comments