@@ -1180,11 +1180,11 @@ static void* dasm_labels[zend_lb_MAX];
1180
1180
|.endmacro
1181
1181
1182
1182
|.macro IF_Z_TYPE, zv, val, label
1183
- | IF_TYPE byte [zv + offsetof(zval, u1.v.type)], val, label
1183
+ | IF_TYPE byte [zv+ offsetof(zval, u1.v.type)], val, label
1184
1184
|.endmacro
1185
1185
1186
1186
|.macro IF_NOT_Z_TYPE, zv, val, label
1187
- | IF_NOT_TYPE byte [zv + offsetof(zval, u1.v.type)], val, label
1187
+ | IF_NOT_TYPE byte [zv+ offsetof(zval, u1.v.type)], val, label
1188
1188
|.endmacro
1189
1189
1190
1190
|.macro CMP_ZVAL_TYPE, addr, val
@@ -8511,9 +8511,14 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
8511
8511
&& call_num_args <= func->op_array.num_args) {
8512
8512
uint32_t num_args;
8513
8513
8514
- if ((func->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0
8515
- && call_info) {
8516
- num_args = skip_valid_arguments(op_array, ssa, call_info);
8514
+ if ((func->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0) {
8515
+ if (trace) {
8516
+ num_args = 0;
8517
+ } else if (call_info) {
8518
+ num_args = skip_valid_arguments(op_array, ssa, call_info);
8519
+ } else {
8520
+ num_args = call_num_args;
8521
+ }
8517
8522
} else {
8518
8523
num_args = call_num_args;
8519
8524
}
@@ -10498,6 +10503,67 @@ static int zend_jit_bind_global(dasm_State **Dst, const zend_op *opline, const z
10498
10503
return 1;
10499
10504
}
10500
10505
10506
+ static int zend_jit_verify_arg_type(dasm_State **Dst, const zend_op *opline, zend_arg_info *arg_info, zend_bool check_exception)
10507
+ {
10508
+ zend_jit_addr res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var);
10509
+ zend_bool in_cold = 0;
10510
+ uint32_t type_mask = ZEND_TYPE_PURE_MASK(arg_info->type);
10511
+ zend_reg tmp_reg = (type_mask == 0 || is_power_of_two(type_mask)) ? ZREG_FCARG1a : ZREG_R0;
10512
+
10513
+ if (ZEND_ARG_SEND_MODE(arg_info)) {
10514
+ if (opline->opcode == ZEND_RECV_INIT) {
10515
+ | GET_ZVAL_PTR Ra(tmp_reg), res_addr
10516
+ | ZVAL_DEREF Ra(tmp_reg), MAY_BE_REF
10517
+ res_addr = ZEND_ADDR_MEM_ZVAL(tmp_reg, 0);
10518
+ } else {
10519
+ | GET_ZVAL_PTR Ra(tmp_reg), res_addr
10520
+ res_addr = ZEND_ADDR_MEM_ZVAL(tmp_reg, offsetof(zend_reference, val));
10521
+ }
10522
+ }
10523
+
10524
+ if (type_mask != 0) {
10525
+ if (is_power_of_two(type_mask)) {
10526
+ uint32_t type_code = concrete_type(type_mask);
10527
+ | IF_NOT_ZVAL_TYPE res_addr, type_code, >1
10528
+ } else {
10529
+ | mov edx, 1
10530
+ | mov cl, byte [Ra(Z_REG(res_addr))+Z_OFFSET(res_addr)+offsetof(zval, u1.v.type)]
10531
+ | shl edx, cl
10532
+ | test edx, type_mask
10533
+ | je >1
10534
+ }
10535
+
10536
+ |.cold_code
10537
+ |1:
10538
+
10539
+ in_cold = 1;
10540
+ }
10541
+
10542
+ if (Z_REG(res_addr) != ZREG_FCARG1a || Z_OFFSET(res_addr) != 0) {
10543
+ | LOAD_ZVAL_ADDR FCARG1a, res_addr
10544
+ }
10545
+ if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) {
10546
+ | SAVE_VALID_OPLINE opline, r0
10547
+ } else {
10548
+ | ADDR_OP2_2 mov, aword EX->opline, opline, r0
10549
+ }
10550
+ | LOAD_ADDR FCARG2a, (ptrdiff_t)arg_info
10551
+ | EXT_CALL zend_jit_verify_arg_slow, r0
10552
+
10553
+ if (check_exception) {
10554
+ | test eax, eax
10555
+ | jz ->exception_handler
10556
+ }
10557
+
10558
+ if (in_cold) {
10559
+ | jmp >1
10560
+ |.code
10561
+ |1:
10562
+ }
10563
+
10564
+ return 1;
10565
+ }
10566
+
10501
10567
static int zend_jit_recv(dasm_State **Dst, const zend_op *opline, const zend_op_array *op_array)
10502
10568
{
10503
10569
uint32_t arg_num = opline->op1.num;
@@ -10528,7 +10594,11 @@ static int zend_jit_recv(dasm_State **Dst, const zend_op *opline, const zend_op_
10528
10594
| jb >1
10529
10595
|.cold_code
10530
10596
|1:
10531
- | SAVE_VALID_OPLINE opline, r0
10597
+ if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) {
10598
+ | SAVE_VALID_OPLINE opline, r0
10599
+ } else {
10600
+ | ADDR_OP2_2 mov, aword EX->opline, opline, r0
10601
+ }
10532
10602
| mov FCARG1a, FP
10533
10603
| EXT_CALL zend_missing_arg_error, r0
10534
10604
| jmp ->exception_handler
@@ -10537,70 +10607,17 @@ static int zend_jit_recv(dasm_State **Dst, const zend_op *opline, const zend_op_
10537
10607
}
10538
10608
10539
10609
if (arg_info) {
10540
- // Type check
10541
- zend_type type = arg_info->type;
10542
- zend_jit_addr res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var);
10543
- uint32_t type_mask;
10544
-
10545
- | LOAD_ZVAL_ADDR r0, res_addr
10546
- if (ZEND_ARG_SEND_MODE(arg_info)) {
10547
- | GET_Z_PTR r0, r0
10548
- | add r0, offsetof(zend_reference, val)
10549
- }
10550
-
10551
- type_mask = ZEND_TYPE_PURE_MASK(type);
10552
- if (type_mask == 0) {
10553
- | jmp >8
10554
- } else if (is_power_of_two(type_mask)) {
10555
- uint32_t type_code = concrete_type(type_mask);
10556
- | cmp byte [r0 + 8], type_code
10557
- | jne >8
10558
- } else {
10559
- | mov edx, 1
10560
- | mov cl, byte [r0 + 8]
10561
- | shl edx, cl
10562
- | test edx, type_mask
10563
- | je >8
10564
- }
10565
-
10566
- |.cold_code
10567
- |8:
10568
- | SAVE_VALID_OPLINE opline, r0
10569
- | mov FCARG1a, r0
10570
- | mov r0, EX->run_time_cache
10571
- | add r0, opline->extended_value
10572
- | mov FCARG2a, EX->func
10573
- |.if X64WIN
10574
- | mov CARG3, arg_num
10575
- | LOAD_ADDR CARG4, (ptrdiff_t)arg_info
10576
- | mov aword A5, r0
10577
- | EXT_CALL zend_jit_verify_arg_slow, r0
10578
- |.elif X64
10579
- | mov CARG3, arg_num
10580
- | LOAD_ADDR CARG4, (ptrdiff_t)arg_info
10581
- | mov CARG5, r0
10582
- | EXT_CALL zend_jit_verify_arg_slow, r0
10583
- |.else
10584
- | sub r4, 4
10585
- | push r0
10586
- | push (ptrdiff_t)arg_info
10587
- | push arg_num
10588
- | EXT_CALL zend_jit_verify_arg_slow, r0
10589
- | add r4, 4
10590
- |.endif
10591
-
10592
- if (!zend_jit_check_exception(Dst)) {
10610
+ if (!zend_jit_verify_arg_type(Dst, opline, arg_info, 1)) {
10593
10611
return 0;
10594
10612
}
10595
- | jmp >1
10596
- |.code
10597
- |1:
10598
10613
}
10599
10614
10600
- if ((opline+1)->opcode != ZEND_RECV && (opline+1)->opcode != ZEND_RECV_INIT) {
10601
- last_valid_opline = NULL;
10602
- if (!zend_jit_set_valid_ip(Dst, opline + 1)) {
10603
- return 0;
10615
+ if (JIT_G(trigger) != ZEND_JIT_ON_HOT_TRACE) {
10616
+ if ((opline+1)->opcode != ZEND_RECV && (opline+1)->opcode != ZEND_RECV_INIT) {
10617
+ last_valid_opline = NULL;
10618
+ if (!zend_jit_set_valid_ip(Dst, opline + 1)) {
10619
+ return 0;
10620
+ }
10604
10621
}
10605
10622
}
10606
10623
@@ -10609,8 +10626,6 @@ static int zend_jit_recv(dasm_State **Dst, const zend_op *opline, const zend_op_
10609
10626
10610
10627
static int zend_jit_recv_init(dasm_State **Dst, const zend_op *opline, const zend_op_array *op_array, zend_bool is_last, int may_throw)
10611
10628
{
10612
- zend_arg_info *arg_info = NULL;
10613
- uint8_t has_slow = 0;
10614
10629
uint32_t arg_num = opline->op1.num;
10615
10630
zval *zv = RT_CONSTANT(opline, opline->op2);
10616
10631
zend_jit_addr res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var);
@@ -10622,31 +10637,45 @@ static int zend_jit_recv_init(dasm_State **Dst, const zend_op *opline, const zen
10622
10637
}
10623
10638
| ZVAL_COPY_CONST res_addr, -1, -1, zv, r0
10624
10639
if (Z_REFCOUNTED_P(zv)) {
10625
- | ADDREF_CONST zv, r0
10640
+ | ADDREF_CONST zv, r0
10626
10641
}
10642
+
10627
10643
if (Z_CONSTANT_P(zv)) {
10628
- has_slow = 1;
10629
- | SAVE_VALID_OPLINE opline, r0
10630
- |.if X64
10631
- | LOAD_ZVAL_ADDR CARG1, res_addr
10632
- | mov r0, EX->func
10633
- | mov CARG2, [r0 + offsetof(zend_op_array, scope)]
10634
- | EXT_CALL zval_update_constant_ex, r0
10635
- |.else
10636
- | sub r4, 8
10637
- | mov r0, EX->func
10638
- | push dword [r0 + offsetof(zend_op_array, scope)]
10639
- | LOAD_ZVAL_ADDR r0, res_addr
10640
- | push r0
10641
- | EXT_CALL zval_update_constant_ex, r0
10642
- | add r4, 16
10643
- |.endif
10644
- | test al, al
10645
- | jnz >7
10644
+ if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) {
10645
+ | SAVE_VALID_OPLINE opline, r0
10646
+ } else {
10647
+ | ADDR_OP2_2 mov, aword EX->opline, opline, r0
10648
+ }
10649
+ |.if X64
10650
+ | LOAD_ZVAL_ADDR CARG1, res_addr
10651
+ | mov r0, EX->func
10652
+ | mov CARG2, [r0 + offsetof(zend_op_array, scope)]
10653
+ | EXT_CALL zval_update_constant_ex, r0
10654
+ |.else
10655
+ | sub r4, 8
10656
+ | mov r0, EX->func
10657
+ | push dword [r0 + offsetof(zend_op_array, scope)]
10658
+ | LOAD_ZVAL_ADDR r0, res_addr
10659
+ | push r0
10660
+ | EXT_CALL zval_update_constant_ex, r0
10661
+ | add r4, 16
10662
+ |.endif
10663
+ | test al, al
10664
+ | jnz >1
10665
+ |.cold_code
10666
+ |1:
10667
+ | ZVAL_PTR_DTOR res_addr, MAY_BE_ANY|MAY_BE_RC1|MAY_BE_RCN, 1, 0, opline
10668
+ | SET_ZVAL_TYPE_INFO res_addr, IS_UNDEF
10669
+ | jmp ->exception_handler
10670
+ |.code
10646
10671
}
10672
+
10647
10673
|5:
10674
+
10648
10675
if (op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
10649
10676
do {
10677
+ zend_arg_info *arg_info;
10678
+
10650
10679
if (arg_num <= op_array->num_args) {
10651
10680
arg_info = &op_array->arg_info[arg_num-1];
10652
10681
} else if (op_array->fn_flags & ZEND_ACC_VARIADIC) {
@@ -10657,81 +10686,24 @@ static int zend_jit_recv_init(dasm_State **Dst, const zend_op *opline, const zen
10657
10686
if (!ZEND_TYPE_IS_SET(arg_info->type)) {
10658
10687
break;
10659
10688
}
10660
- has_slow += 2;
10661
- | LOAD_ZVAL_ADDR r0, res_addr
10662
- | ZVAL_DEREF r0, MAY_BE_REF
10663
-
10664
- uint32_t type_mask = ZEND_TYPE_PURE_MASK(arg_info->type);
10665
- if (type_mask == 0) {
10666
- | jmp >8
10667
- } else if (is_power_of_two(type_mask)) {
10668
- uint32_t type_code = concrete_type(type_mask);
10669
- | cmp byte [r0 + 8], type_code
10670
- | jne >8
10671
- } else {
10672
- | mov edx, 1
10673
- | mov cl, byte [r0 + 8]
10674
- | shl edx, cl
10675
- | test edx, type_mask
10676
- | je >8
10689
+ if (!zend_jit_verify_arg_type(Dst, opline, arg_info, 0)) {
10690
+ return 0;
10677
10691
}
10678
10692
} while (0);
10679
10693
}
10680
- |9:
10694
+
10681
10695
if (may_throw) {
10682
10696
if (!zend_jit_check_exception(Dst)) {
10683
10697
return 0;
10684
10698
}
10685
10699
}
10686
- if (is_last) {
10687
- | LOAD_IP_ADDR (opline + 1)
10688
- last_valid_opline = (opline + 1);
10689
- }
10690
10700
10691
- if (has_slow) {
10692
- |.cold_code
10693
- if (has_slow & 1) {
10694
- |7:
10695
- | ZVAL_PTR_DTOR res_addr, MAY_BE_ANY|MAY_BE_RC1|MAY_BE_RCN, 1, 0, opline
10696
- | SET_ZVAL_TYPE_INFO res_addr, IS_UNDEF
10697
- if (may_throw) {
10698
- if (!zend_jit_check_exception(Dst)) {
10699
- return 0;
10701
+ if (JIT_G(trigger) != ZEND_JIT_ON_HOT_TRACE) {
10702
+ if (is_last) {
10703
+ | LOAD_IP_ADDR (opline + 1)
10704
+ last_valid_opline = (opline + 1);
10700
10705
}
10701
10706
}
10702
- | jmp <5
10703
- }
10704
- if (has_slow & 2) {
10705
- |8:
10706
- | mov FCARG1a, r0
10707
- | mov r0, EX->run_time_cache
10708
- | lea r0, [r0 + opline->extended_value]
10709
- | mov FCARG2a, EX->func
10710
- |.if X64WIN
10711
- | mov CARG3, arg_num
10712
- | LOAD_ADDR CARG4, (ptrdiff_t)arg_info
10713
- | mov aword A5, r0
10714
- | SAVE_VALID_OPLINE opline, r0
10715
- | EXT_CALL zend_jit_verify_arg_slow, r0
10716
- |.elif X64
10717
- | mov CARG3, arg_num
10718
- | LOAD_ADDR CARG4, (ptrdiff_t)arg_info
10719
- | mov CARG5, r0
10720
- | SAVE_VALID_OPLINE opline, r0
10721
- | EXT_CALL zend_jit_verify_arg_slow, r0
10722
- |.else
10723
- | sub r4, 4
10724
- | push r0
10725
- | push (ptrdiff_t)arg_info
10726
- | push arg_num
10727
- | SAVE_VALID_OPLINE opline, r0
10728
- | EXT_CALL zend_jit_verify_arg_slow, r0
10729
- | add r4, 4
10730
- |.endif
10731
- | jmp <9
10732
- }
10733
- |.code
10734
- }
10735
10707
10736
10708
return 1;
10737
10709
}
0 commit comments