@@ -3234,6 +3234,27 @@ static int zend_jit_type_guard(dasm_State **Dst, const zend_op *opline, uint32_t
3234
3234
return 1;
3235
3235
}
3236
3236
3237
+ static int zend_jit_packed_guard(dasm_State **Dst, const zend_op *opline, uint32_t var, uint32_t op_info)
3238
+ {
3239
+ int32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_PACKED_GUARD);
3240
+ const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point);
3241
+
3242
+ if (!exit_addr) {
3243
+ return 0;
3244
+ }
3245
+
3246
+ | GET_ZVAL_LVAL ZREG_FCARG1a, ZEND_ADDR_MEM_ZVAL(ZREG_FP, var)
3247
+ if (op_info & MAY_BE_ARRAY_PACKED) {
3248
+ | test dword [FCARG1a + offsetof(zend_array, u.flags)], HASH_FLAG_PACKED
3249
+ | jz &exit_addr
3250
+ } else {
3251
+ | test dword [FCARG1a + offsetof(zend_array, u.flags)], HASH_FLAG_PACKED
3252
+ | jnz &exit_addr
3253
+ }
3254
+
3255
+ return 1;
3256
+ }
3257
+
3237
3258
static int zend_jit_trace_handler(dasm_State **Dst, const zend_op_array *op_array, const zend_op *opline, int may_throw, zend_jit_trace_rec *trace)
3238
3259
{
3239
3260
zend_jit_op_array_trace_extension *jit_extension =
@@ -4953,12 +4974,27 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
4953
4974
| // if (EXPECTED(Z_TYPE_P(dim) == IS_LONG))
4954
4975
| IF_NOT_ZVAL_TYPE op2_addr, IS_LONG, >3
4955
4976
}
4977
+ if (op1_info & MAY_BE_PACKED_GUARD) {
4978
+ int32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_PACKED_GUARD);
4979
+ const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point);
4980
+
4981
+ if (!exit_addr) {
4982
+ return 0;
4983
+ }
4984
+ if (op1_info & MAY_BE_ARRAY_PACKED) {
4985
+ | test dword [FCARG1a + offsetof(zend_array, u.flags)], HASH_FLAG_PACKED
4986
+ | jz &exit_addr
4987
+ } else {
4988
+ | test dword [FCARG1a + offsetof(zend_array, u.flags)], HASH_FLAG_PACKED
4989
+ | jnz &exit_addr
4990
+ }
4991
+ }
4956
4992
if (type == BP_VAR_W) {
4957
4993
| // hval = Z_LVAL_P(dim);
4958
4994
| GET_ZVAL_LVAL ZREG_FCARG2a, op2_addr
4959
4995
op2_loaded = 1;
4960
4996
}
4961
- if (( op1_info & MAY_BE_ARRAY_KEY_LONG) && (op1_info & MAY_BE_ARRAY_PACKED) ) {
4997
+ if (op1_info & MAY_BE_ARRAY_PACKED) {
4962
4998
if (Z_MODE(op2_addr) == IS_CONST_ZVAL) {
4963
4999
zend_long val = Z_LVAL_P(Z_ZV(op2_addr));
4964
5000
if (val >= 0 && val < HT_MAX_SIZE) {
@@ -5050,7 +5086,7 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
5050
5086
}
5051
5087
switch (type) {
5052
5088
case BP_JIT_IS:
5053
- if (( op1_info & MAY_BE_ARRAY_KEY_LONG) && (op1_info & MAY_BE_ARRAY_HASH) ) {
5089
+ if (op1_info & MAY_BE_ARRAY_HASH) {
5054
5090
|4:
5055
5091
if (!op2_loaded) {
5056
5092
| // hval = Z_LVAL_P(dim);
@@ -5076,9 +5112,9 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
5076
5112
case BP_VAR_IS:
5077
5113
case BP_VAR_UNSET:
5078
5114
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)) {
5115
+ (( op1_info & MAY_BE_ARRAY_PACKED) &&
5116
+ ( Z_MODE(op2_addr) != IS_CONST_ZVAL ||
5117
+ (Z_LVAL_P(Z_ZV(op2_addr)) >= 0 && Z_LVAL_P(Z_ZV(op2_addr)) < HT_MAX_SIZE)) )) {
5082
5118
if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE && type == BP_VAR_R) {
5083
5119
| jmp &exit_addr
5084
5120
} else if (type == BP_VAR_IS && not_found_exit_addr) {
@@ -5087,7 +5123,7 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
5087
5123
| jmp >2 // NOT_FOUND
5088
5124
}
5089
5125
}
5090
- if (( op1_info & MAY_BE_ARRAY_KEY_LONG) && (op1_info & MAY_BE_ARRAY_HASH) ) {
5126
+ if (op1_info & MAY_BE_ARRAY_HASH) {
5091
5127
|4:
5092
5128
if (!op2_loaded) {
5093
5129
| // hval = Z_LVAL_P(dim);
@@ -5140,20 +5176,27 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
5140
5176
| jz >9
5141
5177
break;
5142
5178
case BP_VAR_W:
5143
- |2:
5144
- | //retval = zend_hash_index_add_new(ht, hval, &EG(uninitialized_zval));
5145
- |.if X64
5146
- | LOAD_ADDR_ZTS CARG3, executor_globals, uninitialized_zval
5147
- |.else
5148
- | sub r4, 12
5149
- | PUSH_ADDR_ZTS executor_globals, uninitialized_zval, r0
5150
- |.endif
5151
- | EXT_CALL zend_hash_index_add_new, r0
5152
- |.if not(X64)
5153
- | add r4, 12
5154
- |.endif
5155
- if (op1_info & MAY_BE_ARRAY_KEY_LONG) {
5156
- | jmp >8
5179
+ if (!(op1_info & MAY_BE_ARRAY_KEY_LONG) ||
5180
+ ((op1_info & MAY_BE_ARRAY_PACKED) &&
5181
+ (Z_MODE(op2_addr) != IS_CONST_ZVAL ||
5182
+ (Z_LVAL_P(Z_ZV(op2_addr)) >= 0 && Z_LVAL_P(Z_ZV(op2_addr)) < HT_MAX_SIZE)))) {
5183
+ |2:
5184
+ | //retval = zend_hash_index_add_new(ht, hval, &EG(uninitialized_zval));
5185
+ |.if X64
5186
+ | LOAD_ADDR_ZTS CARG3, executor_globals, uninitialized_zval
5187
+ |.else
5188
+ | sub r4, 12
5189
+ | PUSH_ADDR_ZTS executor_globals, uninitialized_zval, r0
5190
+ |.endif
5191
+ | EXT_CALL zend_hash_index_add_new, r0
5192
+ |.if not(X64)
5193
+ | add r4, 12
5194
+ |.endif
5195
+ if (op1_info & MAY_BE_ARRAY_HASH) {
5196
+ | jmp >8
5197
+ }
5198
+ }
5199
+ if (op1_info & MAY_BE_ARRAY_HASH) {
5157
5200
|4:
5158
5201
| EXT_CALL zend_jit_hash_index_lookup_w, r0
5159
5202
}
0 commit comments