@@ -134,7 +134,7 @@ static uint32_t zend_jit_trace_get_exit_point(const zend_op *from_opline, const
134
134
if (stack_size ) {
135
135
stack = JIT_G (current_frame )-> stack ;
136
136
do {
137
- if (stack [ stack_size - 1 ] != IS_UNKNOWN ) {
137
+ if (STACK_TYPE ( stack , stack_size - 1 ) != IS_UNKNOWN ) {
138
138
break ;
139
139
}
140
140
stack_size -- ;
@@ -320,10 +320,10 @@ static zend_always_inline uint32_t zend_jit_trace_type_to_info(zend_uchar type)
320
320
}
321
321
322
322
#define STACK_VAR_TYPE (_var ) \
323
- ((zend_uchar) stack[ EX_VAR_TO_NUM(_var)] )
323
+ STACK_TYPE( stack, EX_VAR_TO_NUM(_var))
324
324
325
325
#define SET_STACK_VAR_TYPE (_var , _type ) do { \
326
- stack[ EX_VAR_TO_NUM(_var)] = _type; \
326
+ SET_STACK_TYPE( stack, EX_VAR_TO_NUM(_var), _type) ; \
327
327
} while (0)
328
328
329
329
#define CHECK_OP_TRACE_TYPE (_var , _ssa_var , op_info , op_type ) do { \
@@ -575,13 +575,13 @@ static int zend_jit_trace_add_phis(zend_jit_trace_rec *trace_buffer, uint32_t ss
575
575
ZEND_MM_ALIGNED_SIZE (sizeof (int ) * 2 ) +
576
576
sizeof (void * ) * 2 );
577
577
phi -> sources = (int * )(((char * )phi ) + ZEND_MM_ALIGNED_SIZE (sizeof (zend_ssa_phi )));
578
- phi -> sources [0 ] = stack [ k ] ;
578
+ phi -> sources [0 ] = STACK_VAR ( stack , k ) ;
579
579
phi -> sources [1 ] = -1 ;
580
580
phi -> use_chains = (zend_ssa_phi * * )(((char * )phi -> sources ) + ZEND_MM_ALIGNED_SIZE (sizeof (int ) * 2 ));
581
581
phi -> pi = -1 ;
582
582
phi -> var = k ;
583
583
phi -> ssa_var = ssa_vars_count ;
584
- stack [ k ] = ssa_vars_count ;
584
+ SET_STACK_VAR ( stack , k , ssa_vars_count ) ;
585
585
ssa_vars_count ++ ;
586
586
phi -> block = 1 ;
587
587
if (prev ) {
@@ -957,7 +957,7 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
957
957
}
958
958
stack = frame -> stack ;
959
959
for (i = 0 ; i < ssa_vars_count ; i ++ ) {
960
- stack [ i ] = i ;
960
+ SET_STACK_VAR ( stack , i , i ) ;
961
961
}
962
962
963
963
if (trace_buffer -> stop == ZEND_JIT_TRACE_STOP_LOOP ) {
@@ -973,14 +973,14 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
973
973
if (p -> op == ZEND_JIT_TRACE_VM ) {
974
974
opline = p -> opline ;
975
975
ssa_opcodes [idx ] = opline ;
976
- ssa_vars_count = zend_ssa_rename_op (op_array , opline , idx , build_flags , ssa_vars_count , ssa_ops , stack );
976
+ ssa_vars_count = zend_ssa_rename_op (op_array , opline , idx , build_flags , ssa_vars_count , ssa_ops , ( int * ) stack );
977
977
idx ++ ;
978
978
len = zend_jit_trace_op_len (p -> opline );
979
979
while (len > 1 ) {
980
980
opline ++ ;
981
981
ssa_opcodes [idx ] = opline ;
982
982
if (opline -> opcode != ZEND_OP_DATA ) {
983
- ssa_vars_count = zend_ssa_rename_op (op_array , opline , idx , build_flags , ssa_vars_count , ssa_ops , stack );
983
+ ssa_vars_count = zend_ssa_rename_op (op_array , opline , idx , build_flags , ssa_vars_count , ssa_ops , ( int * ) stack );
984
984
}
985
985
idx ++ ;
986
986
len -- ;
@@ -993,7 +993,7 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
993
993
ZEND_ASSERT (ssa_vars_count < 0xff );
994
994
p -> first_ssa_var = ssa_vars_count ;
995
995
for (i = 0 ; i < op_array -> last_var ; i ++ ) {
996
- stack [ i ] = ssa_vars_count ++ ;
996
+ SET_STACK_VAR ( stack , i , ssa_vars_count ++ ) ;
997
997
}
998
998
} else if (p -> op == ZEND_JIT_TRACE_BACK ) {
999
999
op_array = p -> op_array ;
@@ -1003,7 +1003,7 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
1003
1003
ZEND_ASSERT (ssa_vars_count <= 0xff );
1004
1004
p -> first_ssa_var = ssa_vars_count ;
1005
1005
for (i = 0 ; i < op_array -> last_var + op_array -> T ; i ++ ) {
1006
- stack [ i ] = ssa_vars_count ++ ;
1006
+ SET_STACK_VAR ( stack , i , ssa_vars_count ++ ) ;
1007
1007
}
1008
1008
} else {
1009
1009
level -- ;
@@ -1042,7 +1042,7 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
1042
1042
zend_ssa_phi * phi = tssa -> blocks [1 ].phis ;
1043
1043
1044
1044
while (phi ) {
1045
- phi -> sources [1 ] = stack [ phi -> var ] ;
1045
+ phi -> sources [1 ] = STACK_VAR ( stack , phi -> var ) ;
1046
1046
ssa_vars [phi -> ssa_var ].var = phi -> var ;
1047
1047
ssa_vars [phi -> ssa_var ].definition_phi = phi ;
1048
1048
ssa_vars [phi -> sources [0 ]].phi_use_chain = phi ;
@@ -1143,7 +1143,7 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
1143
1143
}
1144
1144
if (i < parent_vars_count ) {
1145
1145
/* Initialize TSSA variable from parent trace */
1146
- zend_uchar op_type = parent_stack [ i ] ;
1146
+ zend_uchar op_type = STACK_TYPE ( parent_stack , i ) ;
1147
1147
1148
1148
if (op_type != IS_UNKNOWN ) {
1149
1149
ssa_var_info [i ].type &= zend_jit_trace_type_to_info (op_type );
@@ -1171,7 +1171,7 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
1171
1171
TRACE_FRAME_INIT (frame , op_array , 0 , 0 );
1172
1172
TRACE_FRAME_SET_RETURN_SSA_VAR (frame , -1 );
1173
1173
for (i = 0 ; i < op_array -> last_var + op_array -> T ; i ++ ) {
1174
- frame -> stack [ i ] = -1 ;
1174
+ SET_STACK_TYPE ( frame -> stack , i , IS_UNKNOWN ) ;
1175
1175
}
1176
1176
memset (& return_value_info , 0 , sizeof (return_value_info ));
1177
1177
@@ -1334,7 +1334,7 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
1334
1334
if (ARG_SHOULD_BE_SENT_BY_REF (frame -> call -> func , opline -> op2 .num )) {
1335
1335
info |= MAY_BE_REF |MAY_BE_RC1 |MAY_BE_RCN |MAY_BE_ANY |MAY_BE_ARRAY_OF_ANY |MAY_BE_ARRAY_KEY_ANY ;
1336
1336
}
1337
- frame -> call -> stack [ opline -> op2 .num - 1 ] = info ;
1337
+ SET_STACK_INFO ( frame -> call -> stack , opline -> op2 .num - 1 , info ) ;
1338
1338
}
1339
1339
break ;
1340
1340
case ZEND_RETURN :
@@ -1476,7 +1476,7 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
1476
1476
TRACE_FRAME_INIT (call , op_array , 0 , 0 );
1477
1477
top = zend_jit_trace_call_frame (top , op_array );
1478
1478
for (i = 0 ; i < op_array -> last_var + op_array -> T ; i ++ ) {
1479
- call -> stack [ i ] = -1 ;
1479
+ SET_STACK_TYPE ( call -> stack , i , IS_UNKNOWN ) ;
1480
1480
}
1481
1481
} else {
1482
1482
ZEND_ASSERT (& call -> func -> op_array == op_array );
@@ -1515,7 +1515,7 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
1515
1515
if (!(op_array -> fn_flags & ZEND_ACC_HAS_TYPE_HINTS )
1516
1516
&& i < op_array -> num_args ) {
1517
1517
/* Propagate argument type */
1518
- ssa_var_info [v ].type &= frame -> stack [ i ] ;
1518
+ ssa_var_info [v ].type &= STACK_INFO ( frame -> stack , i ) ;
1519
1519
}
1520
1520
i ++ ;
1521
1521
v ++ ;
@@ -1582,7 +1582,7 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
1582
1582
TRACE_FRAME_INIT (frame , op_array , 0 , 0 );
1583
1583
TRACE_FRAME_SET_RETURN_SSA_VAR (frame , -1 );
1584
1584
for (i = 0 ; i < op_array -> last_var + op_array -> T ; i ++ ) {
1585
- frame -> stack [ i ] = -1 ;
1585
+ SET_STACK_TYPE ( frame -> stack , i , IS_UNKNOWN ) ;
1586
1586
}
1587
1587
}
1588
1588
@@ -1594,7 +1594,7 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
1594
1594
top = zend_jit_trace_call_frame (top , p -> op_array );
1595
1595
if (p -> func -> type == ZEND_USER_FUNCTION ) {
1596
1596
for (i = 0 ; i < p -> op_array -> last_var + p -> op_array -> T ; i ++ ) {
1597
- call -> stack [ i ] = -1 ;
1597
+ SET_STACK_TYPE ( call -> stack , i , IS_UNKNOWN ) ;
1598
1598
}
1599
1599
}
1600
1600
} else if (p -> op == ZEND_JIT_TRACE_DO_ICALL ) {
@@ -1724,11 +1724,11 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
1724
1724
while (i < op_array -> last_var ) {
1725
1725
if (!(ssa -> var_info [i ].type & MAY_BE_GUARD )
1726
1726
&& has_concrete_type (ssa -> var_info [i ].type )) {
1727
- stack [ i ] = concrete_type (ssa -> var_info [i ].type );
1727
+ SET_STACK_TYPE ( stack , i , concrete_type (ssa -> var_info [i ].type ) );
1728
1728
} else if (i < op_array -> num_args ) {
1729
- stack [ i ] = IS_UNKNOWN ;
1729
+ SET_STACK_TYPE ( stack , i , IS_UNKNOWN ) ;
1730
1730
} else {
1731
- stack [ i ] = IS_UNDEF ;
1731
+ SET_STACK_TYPE ( stack , i , IS_UNDEF ) ;
1732
1732
}
1733
1733
i ++ ;
1734
1734
}
@@ -1749,12 +1749,12 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
1749
1749
while (i < op_array -> last_var + op_array -> T ) {
1750
1750
if (!(ssa -> var_info [i ].type & MAY_BE_GUARD )
1751
1751
&& has_concrete_type (ssa -> var_info [i ].type )) {
1752
- stack [ i ] = concrete_type (ssa -> var_info [i ].type );
1752
+ SET_STACK_TYPE ( stack , i , concrete_type (ssa -> var_info [i ].type ) );
1753
1753
} else if (i < parent_vars_count
1754
- && ( zend_uchar ) parent_stack [ i ] != IS_UNKNOWN ) {
1755
- stack [ i ] = parent_stack [ i ] ;
1754
+ && STACK_TYPE ( parent_stack , i ) != IS_UNKNOWN ) {
1755
+ SET_STACK_TYPE ( stack , i , STACK_TYPE ( parent_stack , i )) ;
1756
1756
} else {
1757
- stack [ i ] = IS_UNKNOWN ;
1757
+ SET_STACK_TYPE ( stack , i , IS_UNKNOWN ) ;
1758
1758
}
1759
1759
i ++ ;
1760
1760
}
@@ -1814,7 +1814,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
1814
1814
goto jit_failure ;
1815
1815
}
1816
1816
ssa -> var_info [i ].type = info & ~MAY_BE_GUARD ;
1817
- stack [ i ] = concrete_type (info );
1817
+ SET_STACK_TYPE ( stack , i , concrete_type (info ) );
1818
1818
}
1819
1819
}
1820
1820
}
@@ -2449,7 +2449,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
2449
2449
for (j = 0 ; j < op_array -> last_var ; j ++ ) {
2450
2450
// TODO: get info from trace ???
2451
2451
uint32_t info = zend_ssa_cv_info (opline , op_array , op_array_ssa , j );
2452
- zend_uchar type = stack [ j ] ;
2452
+ zend_uchar type = STACK_TYPE ( stack , j ) ;
2453
2453
2454
2454
info = zend_jit_trace_type_to_info_ex (type , info );
2455
2455
if (info & (MAY_BE_STRING |MAY_BE_ARRAY |MAY_BE_OBJECT |MAY_BE_RESOURCE |MAY_BE_REF )) {
@@ -2949,18 +2949,18 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
2949
2949
/* Initialize abstract stack using SSA */
2950
2950
if (!(ssa -> var_info [p -> first_ssa_var + i ].type & MAY_BE_GUARD )
2951
2951
&& has_concrete_type (ssa -> var_info [p -> first_ssa_var + i ].type )) {
2952
- call -> stack [ i ] = concrete_type (ssa -> var_info [p -> first_ssa_var + i ].type );
2952
+ SET_STACK_TYPE ( call -> stack , i , concrete_type (ssa -> var_info [p -> first_ssa_var + i ].type ) );
2953
2953
} else {
2954
- call -> stack [ i ] = IS_UNKNOWN ;
2954
+ SET_STACK_TYPE ( call -> stack , i , IS_UNKNOWN ) ;
2955
2955
}
2956
2956
i ++ ;
2957
2957
}
2958
2958
while (i < p -> op_array -> last_var ) {
2959
- call -> stack [ i ] = IS_UNDEF ;
2959
+ SET_STACK_TYPE ( call -> stack , i , IS_UNDEF ) ;
2960
2960
i ++ ;
2961
2961
}
2962
2962
while (i < p -> op_array -> last_var + p -> op_array -> T ) {
2963
- call -> stack [ i ] = IS_UNKNOWN ;
2963
+ SET_STACK_TYPE ( call -> stack , i , IS_UNKNOWN ) ;
2964
2964
i ++ ;
2965
2965
}
2966
2966
} else {
@@ -2994,9 +2994,9 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
2994
2994
/* Initialize abstract stack using SSA */
2995
2995
if (!(ssa -> var_info [p -> first_ssa_var + i ].type & MAY_BE_GUARD )
2996
2996
&& has_concrete_type (ssa -> var_info [p -> first_ssa_var + i ].type )) {
2997
- stack [ i ] = concrete_type (ssa -> var_info [p -> first_ssa_var + i ].type );
2997
+ SET_STACK_TYPE ( stack , i , concrete_type (ssa -> var_info [p -> first_ssa_var + i ].type ) );
2998
2998
} else {
2999
- stack [ i ] = IS_UNKNOWN ;
2999
+ SET_STACK_TYPE ( stack , i , IS_UNKNOWN ) ;
3000
3000
}
3001
3001
}
3002
3002
}
@@ -3024,15 +3024,15 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
3024
3024
i = 0 ;
3025
3025
while (i < p -> op_array -> num_args ) {
3026
3026
/* Types of arguments are going to be stored in abstract stack when proseccin SEV onstruction */
3027
- call -> stack [ i ] = IS_UNKNOWN ;
3027
+ SET_STACK_TYPE ( call -> stack , i , IS_UNKNOWN ) ;
3028
3028
i ++ ;
3029
3029
}
3030
3030
while (i < p -> op_array -> last_var ) {
3031
- call -> stack [ i ] = IS_UNDEF ;
3031
+ SET_STACK_TYPE ( call -> stack , i , IS_UNDEF ) ;
3032
3032
i ++ ;
3033
3033
}
3034
3034
while (i < p -> op_array -> last_var + p -> op_array -> T ) {
3035
- call -> stack [ i ] = IS_UNKNOWN ;
3035
+ SET_STACK_TYPE ( call -> stack , i , IS_UNKNOWN ) ;
3036
3036
i ++ ;
3037
3037
}
3038
3038
}
@@ -3886,7 +3886,22 @@ int ZEND_FASTCALL zend_jit_trace_exit(uint32_t exit_num, zend_jit_registers_buf
3886
3886
const zend_op * opline ;
3887
3887
zend_jit_trace_info * t = & zend_jit_traces [trace_num ];
3888
3888
3889
- // TODO: Deoptimizatoion of VM stack state ???
3889
+ /* Deoptimizatoion of VM stack state */
3890
+ uint32_t i ;
3891
+ uint32_t stack_size = t -> exit_info [exit_num ].stack_size ;
3892
+ zend_jit_trace_stack * stack = t -> stack_map + t -> exit_info [exit_num ].stack_offset ;
3893
+
3894
+ for (i = 0 ; i < stack_size ; i ++ ) {
3895
+ if (STACK_REG (stack , i ) != ZREG_NONE ) {
3896
+ if (STACK_TYPE (stack , i ) == IS_LONG ) {
3897
+ ZVAL_LONG (EX_VAR_NUM (i ), regs -> r [STACK_REG (stack , i )]);
3898
+ } else if (STACK_TYPE (stack , i ) == IS_DOUBLE ) {
3899
+ ZVAL_DOUBLE (EX_VAR_NUM (i ), regs -> xmm [STACK_REG (stack , i ) - ZREG_XMM0 ]);
3900
+ } else {
3901
+ ZEND_ASSERT (0 );
3902
+ }
3903
+ }
3904
+ }
3890
3905
3891
3906
/* Lock-free check if the side trace was already JIT-ed or blacklist-ed in another process */
3892
3907
// TODO: We may remoive this, becaus of the same check in zend_jit_trace_hot_side() ???
0 commit comments