@@ -28,8 +28,6 @@ static const void **zend_jit_exit_groups = NULL;
28
28
#define ZEND_JIT_TRACE_STOP_DESCRIPTION (name , description ) \
29
29
description,
30
30
31
- #define USE_ABSTRACT_STACK_FOR_RES_USE_INFO 1
32
-
33
31
static const char * zend_jit_trace_stop_description [] = {
34
32
ZEND_JIT_TRACE_STOP (ZEND_JIT_TRACE_STOP_DESCRIPTION )
35
33
};
@@ -3574,6 +3572,37 @@ static bool zend_jit_may_skip_comparison(const zend_op *opline, const zend_ssa_o
3574
3572
return 0 ;
3575
3573
}
3576
3574
3575
+ static bool zend_jit_trace_next_is_send_result (const zend_op * opline ,
3576
+ zend_jit_trace_rec * p ,
3577
+ zend_jit_trace_stack_frame * frame )
3578
+ {
3579
+ if (opline -> result_type == IS_TMP_VAR
3580
+ && (p + 1 )-> op == ZEND_JIT_TRACE_VM
3581
+ && (p + 1 )-> opline == opline + 1
3582
+ && ((opline + 1 )-> opcode == ZEND_SEND_VAL
3583
+ || ((opline + 1 )-> opcode == ZEND_SEND_VAL_EX
3584
+ && frame
3585
+ && frame -> call
3586
+ && frame -> call -> func
3587
+ && !ARG_MUST_BE_SENT_BY_REF (frame -> call -> func , (opline + 1 )-> op2 .num )))
3588
+ && (opline + 1 )-> op1_type == IS_TMP_VAR
3589
+ && (opline + 1 )-> op2_type != IS_CONST /* Named parameters not supported in JIT */
3590
+ && (opline + 1 )-> op1 .var == opline -> result .var ) {
3591
+
3592
+ if (frame -> call
3593
+ && frame -> call -> func
3594
+ && frame -> call -> func -> type == ZEND_USER_FUNCTION ) {
3595
+ uint8_t res_type = (p + 1 )-> op1_type ;
3596
+
3597
+ if (res_type != IS_UNKNOWN && !(res_type & IS_TRACE_REFERENCE ) ) {
3598
+ zend_jit_trace_send_type (opline + 1 , frame -> call , res_type );
3599
+ }
3600
+ }
3601
+ return 1 ;
3602
+ }
3603
+ return 0 ;
3604
+ }
3605
+
3577
3606
static const void * zend_jit_trace (zend_jit_trace_rec * trace_buffer , uint32_t parent_trace , uint32_t exit_num )
3578
3607
{
3579
3608
const void * handler = NULL ;
@@ -3930,22 +3959,9 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
3930
3959
break ;
3931
3960
}
3932
3961
if (opline -> result_type != IS_UNUSED ) {
3933
- #if USE_ABSTRACT_STACK_FOR_RES_USE_INFO
3934
3962
res_use_info = zend_jit_trace_type_to_info (
3935
3963
STACK_MEM_TYPE (stack , EX_VAR_TO_NUM (opline -> result .var )))
3936
3964
& (MAY_BE_UNDEF |MAY_BE_NULL |MAY_BE_FALSE |MAY_BE_TRUE |MAY_BE_LONG |MAY_BE_DOUBLE );
3937
- #else
3938
- res_use_info = -1 ;
3939
- if (opline -> result_type == IS_CV ) {
3940
- zend_jit_addr res_use_addr = RES_USE_REG_ADDR ();
3941
-
3942
- if (Z_MODE (res_use_addr ) != IS_REG
3943
- || Z_LOAD (res_use_addr )
3944
- || Z_STORE (res_use_addr )) {
3945
- res_use_info = RES_USE_INFO ();
3946
- }
3947
- }
3948
- #endif
3949
3965
res_info = RES_INFO ();
3950
3966
res_addr = RES_REG_ADDR ();
3951
3967
} else {
@@ -3997,55 +4013,17 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
3997
4013
}
3998
4014
res_addr = RES_REG_ADDR ();
3999
4015
if (Z_MODE (res_addr ) != IS_REG
4000
- && opline -> result_type == IS_TMP_VAR
4001
- && (p + 1 )-> op == ZEND_JIT_TRACE_VM
4002
- && (p + 1 )-> opline == opline + 1
4003
- && ((opline + 1 )-> opcode == ZEND_SEND_VAL
4004
- || ((opline + 1 )-> opcode == ZEND_SEND_VAL_EX
4005
- && frame
4006
- && frame -> call
4007
- && frame -> call -> func
4008
- && !ARG_MUST_BE_SENT_BY_REF (frame -> call -> func , (opline + 1 )-> op2 .num )))
4009
- && (opline + 1 )-> op1_type == IS_TMP_VAR
4010
- && (opline + 1 )-> op2_type != IS_CONST /* Named parameters not supported in JIT */
4011
- && (opline + 1 )-> op1 .var == opline -> result .var ) {
4012
- p ++ ;
4013
- if (frame -> call ) {
4014
- uint8_t res_type = p -> op1_type ;
4015
- if (res_type & IS_TRACE_REFERENCE ) {
4016
- res_type = IS_UNKNOWN ;
4017
- }
4018
- if (res_type != IS_UNKNOWN ) {
4019
- zend_jit_trace_send_type (opline + 1 , frame -> call , res_type );
4020
- }
4021
- }
4022
- while ((p + 1 )-> op == ZEND_JIT_TRACE_OP1_TYPE ||
4023
- (p + 1 )-> op == ZEND_JIT_TRACE_OP2_TYPE ) {
4024
- p ++ ;
4025
- }
4016
+ && zend_jit_trace_next_is_send_result (opline , p , frame )) {
4026
4017
send_result = 1 ;
4027
4018
res_use_info = -1 ;
4028
4019
res_addr = ZEND_ADDR_MEM_ZVAL (ZREG_RX , (opline + 1 )-> result .var );
4029
4020
if (!zend_jit_reuse_ip (& dasm_state )) {
4030
4021
goto jit_failure ;
4031
4022
}
4032
4023
} else {
4033
- #if USE_ABSTRACT_STACK_FOR_RES_USE_INFO
4034
4024
res_use_info = zend_jit_trace_type_to_info (
4035
4025
STACK_MEM_TYPE (stack , EX_VAR_TO_NUM (opline -> result .var )))
4036
4026
& (MAY_BE_UNDEF |MAY_BE_NULL |MAY_BE_FALSE |MAY_BE_TRUE |MAY_BE_LONG |MAY_BE_DOUBLE );
4037
- #else
4038
- res_use_info = -1 ;
4039
- if (opline -> result_type == IS_CV ) {
4040
- zend_jit_addr res_use_addr = RES_USE_REG_ADDR ();
4041
-
4042
- if (Z_MODE (res_use_addr ) != IS_REG
4043
- || Z_LOAD (res_use_addr )
4044
- || Z_STORE (res_use_addr )) {
4045
- res_use_info = RES_USE_INFO ();
4046
- }
4047
- }
4048
- #endif
4049
4027
}
4050
4028
res_info = RES_INFO ();
4051
4029
if (!zend_jit_long_math (& dasm_state , opline ,
@@ -4077,57 +4055,17 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
4077
4055
}
4078
4056
res_addr = RES_REG_ADDR ();
4079
4057
if (Z_MODE (res_addr ) != IS_REG
4080
- && opline -> result_type == IS_TMP_VAR
4081
- && (p + 1 )-> op == ZEND_JIT_TRACE_VM
4082
- && (p + 1 )-> opline == opline + 1
4083
- && ((opline + 1 )-> opcode == ZEND_SEND_VAL
4084
- || ((opline + 1 )-> opcode == ZEND_SEND_VAL_EX
4085
- && frame
4086
- && frame -> call
4087
- && frame -> call -> func
4088
- && !ARG_MUST_BE_SENT_BY_REF (frame -> call -> func , (opline + 1 )-> op2 .num )))
4089
- && (opline + 1 )-> op1_type == IS_TMP_VAR
4090
- && (opline + 1 )-> op2_type != IS_CONST /* Named parameters not supported in JIT */
4091
- && (opline + 1 )-> op1 .var == opline -> result .var ) {
4092
- p ++ ;
4093
- if (frame -> call
4094
- && frame -> call -> func
4095
- && frame -> call -> func -> type == ZEND_USER_FUNCTION ) {
4096
- uint8_t res_type = p -> op1_type ;
4097
- if (res_type & IS_TRACE_REFERENCE ) {
4098
- res_type = IS_UNKNOWN ;
4099
- }
4100
- if (res_type != IS_UNKNOWN ) {
4101
- zend_jit_trace_send_type (opline + 1 , frame -> call , res_type );
4102
- }
4103
- }
4104
- while ((p + 1 )-> op == ZEND_JIT_TRACE_OP1_TYPE ||
4105
- (p + 1 )-> op == ZEND_JIT_TRACE_OP2_TYPE ) {
4106
- p ++ ;
4107
- }
4058
+ && zend_jit_trace_next_is_send_result (opline , p , frame )) {
4108
4059
send_result = 1 ;
4109
4060
res_use_info = -1 ;
4110
4061
res_addr = ZEND_ADDR_MEM_ZVAL (ZREG_RX , (opline + 1 )-> result .var );
4111
4062
if (!zend_jit_reuse_ip (& dasm_state )) {
4112
4063
goto jit_failure ;
4113
4064
}
4114
4065
} else {
4115
- #if USE_ABSTRACT_STACK_FOR_RES_USE_INFO
4116
4066
res_use_info = zend_jit_trace_type_to_info (
4117
4067
STACK_MEM_TYPE (stack , EX_VAR_TO_NUM (opline -> result .var )))
4118
4068
& (MAY_BE_UNDEF |MAY_BE_NULL |MAY_BE_FALSE |MAY_BE_TRUE |MAY_BE_LONG |MAY_BE_DOUBLE );
4119
- #else
4120
- res_use_info = -1 ;
4121
- if (opline -> result_type == IS_CV ) {
4122
- zend_jit_addr res_use_addr = RES_USE_REG_ADDR ();
4123
-
4124
- if (Z_MODE (res_use_addr ) != IS_REG
4125
- || Z_LOAD (res_use_addr )
4126
- || Z_STORE (res_use_addr )) {
4127
- res_use_info = RES_USE_INFO ();
4128
- }
4129
- }
4130
- #endif
4131
4069
}
4132
4070
res_info = RES_INFO ();
4133
4071
if (opline -> opcode == ZEND_ADD &&
@@ -4165,35 +4103,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
4165
4103
break ;
4166
4104
}
4167
4105
res_addr = RES_REG_ADDR ();
4168
- if (Z_MODE (res_addr ) != IS_REG
4169
- && opline -> result_type == IS_TMP_VAR
4170
- && (p + 1 )-> op == ZEND_JIT_TRACE_VM
4171
- && (p + 1 )-> opline == opline + 1
4172
- && ((opline + 1 )-> opcode == ZEND_SEND_VAL
4173
- || ((opline + 1 )-> opcode == ZEND_SEND_VAL_EX
4174
- && frame
4175
- && frame -> call
4176
- && frame -> call -> func
4177
- && !ARG_MUST_BE_SENT_BY_REF (frame -> call -> func , (opline + 1 )-> op2 .num )))
4178
- && (opline + 1 )-> op1_type == IS_TMP_VAR
4179
- && (opline + 1 )-> op2_type != IS_CONST /* Named parameters not supported in JIT */
4180
- && (opline + 1 )-> op1 .var == opline -> result .var ) {
4181
- p ++ ;
4182
- if (frame -> call
4183
- && frame -> call -> func
4184
- && frame -> call -> func -> type == ZEND_USER_FUNCTION ) {
4185
- uint8_t res_type = p -> op1_type ;
4186
- if (res_type & IS_TRACE_REFERENCE ) {
4187
- res_type = IS_UNKNOWN ;
4188
- }
4189
- if (res_type != IS_UNKNOWN ) {
4190
- zend_jit_trace_send_type (opline + 1 , frame -> call , res_type );
4191
- }
4192
- }
4193
- while ((p + 1 )-> op == ZEND_JIT_TRACE_OP1_TYPE ||
4194
- (p + 1 )-> op == ZEND_JIT_TRACE_OP2_TYPE ) {
4195
- p ++ ;
4196
- }
4106
+ if (zend_jit_trace_next_is_send_result (opline , p , frame )) {
4197
4107
send_result = 1 ;
4198
4108
res_addr = ZEND_ADDR_MEM_ZVAL (ZREG_RX , (opline + 1 )-> result .var );
4199
4109
if (!zend_jit_reuse_ip (& dasm_state )) {
@@ -4616,34 +4526,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
4616
4526
res_addr = RES_REG_ADDR ();
4617
4527
res_info = RES_INFO ();
4618
4528
if (Z_MODE (res_addr ) != IS_REG
4619
- && opline -> result_type == IS_TMP_VAR
4620
- && (p + 1 )-> op == ZEND_JIT_TRACE_VM
4621
- && (p + 1 )-> opline == opline + 1
4622
- && ((opline + 1 )-> opcode == ZEND_SEND_VAL
4623
- || ((opline + 1 )-> opcode == ZEND_SEND_VAL_EX
4624
- && frame
4625
- && frame -> call
4626
- && frame -> call -> func
4627
- && !ARG_MUST_BE_SENT_BY_REF (frame -> call -> func , (opline + 1 )-> op2 .num )))
4628
- && (opline + 1 )-> op1_type == IS_TMP_VAR
4629
- && (opline + 1 )-> op2_type != IS_CONST /* Named parameters not supported in JIT */
4630
- && (opline + 1 )-> op1 .var == opline -> result .var ) {
4631
- p ++ ;
4632
- if (frame -> call
4633
- && frame -> call -> func
4634
- && frame -> call -> func -> type == ZEND_USER_FUNCTION ) {
4635
- uint8_t res_type = p -> op1_type ;
4636
- if (res_type & IS_TRACE_REFERENCE ) {
4637
- res_type = IS_UNKNOWN ;
4638
- }
4639
- if (res_type != IS_UNKNOWN ) {
4640
- zend_jit_trace_send_type (opline + 1 , frame -> call , res_type );
4641
- }
4642
- }
4643
- while ((p + 1 )-> op == ZEND_JIT_TRACE_OP1_TYPE ||
4644
- (p + 1 )-> op == ZEND_JIT_TRACE_OP2_TYPE ) {
4645
- p ++ ;
4646
- }
4529
+ && zend_jit_trace_next_is_send_result (opline , p , frame )) {
4647
4530
send_result = 1 ;
4648
4531
res_addr = ZEND_ADDR_MEM_ZVAL (ZREG_RX , (opline + 1 )-> result .var );
4649
4532
if (!zend_jit_reuse_ip (& dasm_state )) {
@@ -4682,13 +4565,9 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
4682
4565
op1_info = OP1_INFO ();
4683
4566
CHECK_OP1_TRACE_TYPE ();
4684
4567
res_info = RES_INFO ();
4685
- #if USE_ABSTRACT_STACK_FOR_RES_USE_INFO
4686
4568
res_use_info = zend_jit_trace_type_to_info (
4687
4569
STACK_MEM_TYPE (stack , EX_VAR_TO_NUM (opline -> result .var )))
4688
4570
& (MAY_BE_UNDEF |MAY_BE_NULL |MAY_BE_FALSE |MAY_BE_TRUE |MAY_BE_LONG |MAY_BE_DOUBLE );
4689
- #else
4690
- res_use_info = MAY_BE_UNDEF |MAY_BE_NULL |MAY_BE_FALSE |MAY_BE_TRUE |MAY_BE_LONG |MAY_BE_DOUBLE ;
4691
- #endif
4692
4571
if (!zend_jit_qm_assign (& dasm_state , opline ,
4693
4572
op1_info , op1_addr , op1_def_addr ,
4694
4573
res_use_info , res_info , RES_REG_ADDR ())) {
@@ -6077,6 +5956,10 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
6077
5956
6078
5957
if (send_result ) {
6079
5958
ssa_op ++ ;
5959
+ p ++ ;
5960
+ if ((p + 1 )-> op == ZEND_JIT_TRACE_OP1_TYPE ) {
5961
+ p ++ ;
5962
+ }
6080
5963
send_result = 0 ;
6081
5964
}
6082
5965
}
0 commit comments