@@ -2867,12 +2867,47 @@ static int zend_jit_check_exception_undef_result(dasm_State **Dst, const zend_op
2867
2867
return zend_jit_check_exception(Dst);
2868
2868
}
2869
2869
2870
- static int zend_jit_trace_begin(dasm_State **Dst, uint32_t trace_num)
2870
+ static int zend_jit_trace_begin(dasm_State **Dst, uint32_t trace_num, zend_jit_trace_info *parent, uint32_t exit_num )
2871
2871
{
2872
+ zend_regset regset = ZEND_REGSET_SCRATCH;
2873
+
2874
+ #if ZTS
2875
+ if (1) {
2876
+ #else
2877
+ if ((sizeof(void*) == 8 && !IS_32BIT(&EG(jit_trace_num)))) {
2878
+ #endif
2879
+ /* assignment to EG(jit_trace_num) shouldn't clober CPU register used by deoptimizer */
2880
+ if (parent) {
2881
+ int i;
2882
+ int parent_vars_count = parent->exit_info[exit_num].stack_size;
2883
+ zend_jit_trace_stack *parent_stack =
2884
+ parent->stack_map +
2885
+ parent->exit_info[exit_num].stack_offset;
2886
+
2887
+ for (i = 0; i < parent_vars_count; i++) {
2888
+ if (STACK_REG(parent_stack, i) != ZREG_NONE) {
2889
+ if (STACK_REG(parent_stack, i) < ZREG_NUM) {
2890
+ ZEND_REGSET_EXCL(regset, STACK_REG(parent_stack, i));
2891
+ } else if (STACK_REG(parent_stack, i) == ZREG_ZVAL_COPY_R0) {
2892
+ ZEND_REGSET_EXCL(regset, ZREG_R0);
2893
+ }
2894
+ }
2895
+ }
2896
+ }
2897
+ }
2898
+
2872
2899
current_trace_num = trace_num;
2873
2900
2874
2901
| // EG(jit_trace_num) = trace_num;
2875
- | MEM_OP2_1_ZTS mov, dword, executor_globals, jit_trace_num, trace_num, r0
2902
+ if (regset == ZEND_REGSET_EMPTY) {
2903
+ | push r0
2904
+ | MEM_OP2_1_ZTS mov, dword, executor_globals, jit_trace_num, trace_num, r0
2905
+ | pop r0
2906
+ } else {
2907
+ zend_reg tmp = ZEND_REGSET_FIRST(regset);
2908
+
2909
+ | MEM_OP2_1_ZTS mov, dword, executor_globals, jit_trace_num, trace_num, Ra(tmp)
2910
+ }
2876
2911
2877
2912
return 1;
2878
2913
}
0 commit comments