@@ -1587,6 +1587,20 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
1587
1587
}
1588
1588
ADD_OP2_TRACE_GUARD ();
1589
1589
}
1590
+ if (op1_type == IS_ARRAY
1591
+ && !(orig_op1_type & IS_TRACE_PACKED )
1592
+ && ((opline -> op2_type == IS_CONST
1593
+ && Z_TYPE_P (RT_CONSTANT (opline , opline -> op2 )) == IS_LONG )
1594
+ || (opline -> op2_type != IS_CONST
1595
+ && op2_type == IS_LONG ))) {
1596
+
1597
+ zend_ssa_var_info * info = & tssa -> var_info [tssa -> ops [idx ].op1_use ];
1598
+
1599
+ if (MAY_BE_PACKED (info -> type ) && MAY_BE_HASH (info -> type )) {
1600
+ info -> type |= MAY_BE_PACKED_GUARD ;
1601
+ info -> type &= ~MAY_BE_ARRAY_PACKED ;
1602
+ }
1603
+ }
1590
1604
break ;
1591
1605
case ZEND_ASSIGN_OBJ_OP :
1592
1606
if (opline -> extended_value == ZEND_POW
@@ -1734,22 +1748,19 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
1734
1748
ADD_OP1_TRACE_GUARD ();
1735
1749
ADD_OP2_TRACE_GUARD ();
1736
1750
1737
- if (opline -> op1_type != IS_CONST
1738
- && op1_type == IS_ARRAY
1751
+ if (op1_type == IS_ARRAY
1752
+ && opline -> op1_type != IS_CONST
1739
1753
&& ((opline -> op2_type == IS_CONST
1740
1754
&& Z_TYPE_P (RT_CONSTANT (opline , opline -> op2 )) == IS_LONG )
1741
1755
|| (opline -> op2_type != IS_CONST
1742
1756
&& op2_type == IS_LONG ))) {
1743
1757
1744
1758
zend_ssa_var_info * info = & tssa -> var_info [tssa -> ops [idx ].op1_use ];
1745
1759
1746
- if ((info -> type & MAY_BE_ARRAY_PACKED )
1747
- && (info -> type & MAY_BE_ARRAY_HASH )
1748
- && orig_op1_type != IS_UNKNOWN
1749
- && !(orig_op1_type & IS_TRACE_REFERENCE )) {
1760
+ if (MAY_BE_PACKED (info -> type ) && MAY_BE_HASH (info -> type )) {
1750
1761
info -> type |= MAY_BE_PACKED_GUARD ;
1751
1762
if (orig_op1_type & IS_TRACE_PACKED ) {
1752
- info -> type &= ~MAY_BE_ARRAY_HASH ;
1763
+ info -> type &= ~( MAY_BE_ARRAY_NUMERIC_HASH | MAY_BE_ARRAY_STRING_HASH ) ;
1753
1764
} else {
1754
1765
info -> type &= ~MAY_BE_ARRAY_PACKED ;
1755
1766
}
@@ -1767,6 +1778,20 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
1767
1778
}
1768
1779
ADD_OP1_TRACE_GUARD ();
1769
1780
ADD_OP2_TRACE_GUARD ();
1781
+ if (op1_type == IS_ARRAY
1782
+ && !(orig_op1_type & IS_TRACE_PACKED )
1783
+ && ((opline -> op2_type == IS_CONST
1784
+ && Z_TYPE_P (RT_CONSTANT (opline , opline -> op2 )) == IS_LONG )
1785
+ || (opline -> op2_type != IS_CONST
1786
+ && op2_type == IS_LONG ))) {
1787
+
1788
+ zend_ssa_var_info * info = & tssa -> var_info [tssa -> ops [idx ].op1_use ];
1789
+
1790
+ if (MAY_BE_PACKED (info -> type ) && MAY_BE_HASH (info -> type )) {
1791
+ info -> type |= MAY_BE_PACKED_GUARD ;
1792
+ info -> type &= ~MAY_BE_ARRAY_PACKED ;
1793
+ }
1794
+ }
1770
1795
break ;
1771
1796
case ZEND_SEND_VAL_EX :
1772
1797
case ZEND_SEND_VAR_EX :
@@ -2293,35 +2318,80 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
2293
2318
ssa = & jit_extension -> func_info .ssa ;
2294
2319
2295
2320
while (phi ) {
2296
- uint32_t t = ssa_var_info [phi -> ssa_var ].type ;
2297
- uint32_t t0 = ssa_var_info [phi -> sources [0 ]].type ;
2298
- uint32_t t1 = ssa_var_info [phi -> sources [1 ]].type ;
2321
+ uint32_t t = ssa_var_info [phi -> ssa_var ].type ;
2299
2322
2300
- if (t & MAY_BE_GUARD ) {
2301
- if (tssa -> vars [phi -> ssa_var ].alias != NO_ALIAS ) {
2302
- /* pass */
2303
- } else if (((t0 | t1 ) & (MAY_BE_ANY |MAY_BE_UNDEF |MAY_BE_REF )) == (t & (MAY_BE_ANY |MAY_BE_UNDEF |MAY_BE_REF ))) {
2323
+ if ((t & MAY_BE_GUARD ) && tssa -> vars [phi -> ssa_var ].alias == NO_ALIAS ) {
2324
+ uint32_t t0 = ssa_var_info [phi -> sources [0 ]].type ;
2325
+ uint32_t t1 = ssa_var_info [phi -> sources [1 ]].type ;
2326
+
2327
+ if (((t0 | t1 ) & (MAY_BE_ANY |MAY_BE_UNDEF |MAY_BE_REF )) == (t & (MAY_BE_ANY |MAY_BE_UNDEF |MAY_BE_REF ))) {
2304
2328
if (!((t0 | t1 ) & MAY_BE_GUARD )) {
2305
2329
ssa_var_info [phi -> ssa_var ].type = t & ~MAY_BE_GUARD ;
2306
2330
}
2307
2331
} else if ((t1 & (MAY_BE_ANY |MAY_BE_UNDEF |MAY_BE_REF )) == (t & (MAY_BE_ANY |MAY_BE_UNDEF |MAY_BE_REF ))) {
2308
2332
if (!(t1 & MAY_BE_GUARD )
2309
2333
|| is_checked_guard (tssa , ssa_opcodes , phi -> sources [1 ], phi -> ssa_var )) {
2310
2334
ssa_var_info [phi -> ssa_var ].type = t & ~MAY_BE_GUARD ;
2311
- ssa_var_info [phi -> sources [0 ]].type = t | MAY_BE_GUARD ;
2335
+ t0 = (t & (MAY_BE_ANY |MAY_BE_UNDEF |MAY_BE_REF )) |
2336
+ (t0 & ~(MAY_BE_ANY |MAY_BE_UNDEF |MAY_BE_REF )) |
2337
+ MAY_BE_GUARD ;
2338
+ if (!(t0 & MAY_BE_ARRAY )) {
2339
+ t0 &= ~(MAY_BE_ARRAY_OF_ANY |MAY_BE_ARRAY_OF_REF |MAY_BE_ARRAY_KEY_ANY );
2340
+ }
2341
+ if (!(t0 & (MAY_BE_STRING |MAY_BE_ARRAY |MAY_BE_OBJECT |MAY_BE_RESOURCE ))) {
2342
+ t0 &= ~(MAY_BE_RC1 |MAY_BE_RCN );
2343
+ }
2344
+ ssa_var_info [phi -> sources [0 ]].type = t0 ;
2345
+ ssa_var_info [phi -> sources [0 ]].type = t0 ;
2312
2346
}
2313
2347
} else {
2314
2348
if ((t0 & (MAY_BE_ANY |MAY_BE_UNDEF |MAY_BE_REF )) != (t & (MAY_BE_ANY |MAY_BE_UNDEF |MAY_BE_REF ))) {
2315
- ssa_var_info [phi -> sources [0 ]].type = MAY_BE_GUARD | (t & t0 );
2349
+ t0 = (t & t0 & (MAY_BE_ANY |MAY_BE_UNDEF |MAY_BE_REF )) |
2350
+ (t0 & ~(MAY_BE_ANY |MAY_BE_UNDEF |MAY_BE_REF )) |
2351
+ MAY_BE_GUARD ;
2352
+ if (!(t0 & MAY_BE_ARRAY )) {
2353
+ t0 &= ~(MAY_BE_ARRAY_OF_ANY |MAY_BE_ARRAY_OF_REF |MAY_BE_ARRAY_KEY_ANY );
2354
+ }
2355
+ if (!(t0 & (MAY_BE_STRING |MAY_BE_ARRAY |MAY_BE_OBJECT |MAY_BE_RESOURCE ))) {
2356
+ t0 &= ~(MAY_BE_RC1 |MAY_BE_RCN );
2357
+ }
2358
+ ssa_var_info [phi -> sources [0 ]].type = t0 ;
2316
2359
}
2317
2360
if ((t1 & (MAY_BE_ANY |MAY_BE_UNDEF |MAY_BE_REF )) != (t & (MAY_BE_ANY |MAY_BE_UNDEF |MAY_BE_REF ))) {
2318
2361
if (((t & t1 ) & (MAY_BE_ANY |MAY_BE_UNDEF |MAY_BE_REF )) != 0
2319
2362
&& is_checked_guard (tssa , ssa_opcodes , phi -> sources [1 ], phi -> ssa_var )) {
2320
- ssa_var_info [phi -> sources [1 ]].type = MAY_BE_GUARD | (t & t1 );
2363
+ t1 = (t & t1 & (MAY_BE_ANY |MAY_BE_UNDEF |MAY_BE_REF )) |
2364
+ (t1 & ~(MAY_BE_ANY |MAY_BE_UNDEF |MAY_BE_REF )) |
2365
+ MAY_BE_GUARD ;
2366
+ if (!(t1 & MAY_BE_ARRAY )) {
2367
+ t1 &= ~(MAY_BE_ARRAY_OF_ANY |MAY_BE_ARRAY_OF_REF |MAY_BE_ARRAY_KEY_ANY );
2368
+ }
2369
+ if (!(t1 & (MAY_BE_STRING |MAY_BE_ARRAY |MAY_BE_OBJECT |MAY_BE_RESOURCE ))) {
2370
+ t1 &= ~(MAY_BE_RC1 |MAY_BE_RCN );
2371
+ }
2372
+ ssa_var_info [phi -> sources [1 ]].type = t1 ;
2321
2373
ssa_var_info [phi -> ssa_var ].type = t & ~MAY_BE_GUARD ;
2322
2374
}
2323
2375
}
2324
2376
}
2377
+ t = ssa_var_info [phi -> ssa_var ].type ;
2378
+ }
2379
+
2380
+ if ((t & MAY_BE_PACKED_GUARD ) && tssa -> vars [phi -> ssa_var ].alias == NO_ALIAS ) {
2381
+ uint32_t t0 = ssa_var_info [phi -> sources [0 ]].type ;
2382
+ uint32_t t1 = ssa_var_info [phi -> sources [1 ]].type ;
2383
+
2384
+ if (((t0 | t1 ) & MAY_BE_ARRAY_KEY_ANY ) == (t & MAY_BE_ARRAY_KEY_ANY )) {
2385
+ if (!((t0 | t1 ) & MAY_BE_PACKED_GUARD )) {
2386
+ ssa_var_info [phi -> ssa_var ].type = t & ~MAY_BE_PACKED_GUARD ;
2387
+ }
2388
+ } else if ((t1 & MAY_BE_ARRAY_KEY_ANY ) == (t & MAY_BE_ARRAY_KEY_ANY )) {
2389
+ if (!(t1 & MAY_BE_PACKED_GUARD )) {
2390
+ ssa_var_info [phi -> ssa_var ].type = t & ~MAY_BE_PACKED_GUARD ;
2391
+ ssa_var_info [phi -> sources [0 ]].type =
2392
+ (t0 & ~MAY_BE_ARRAY_KEY_ANY ) | (t & MAY_BE_ARRAY_KEY_ANY ) | MAY_BE_PACKED_GUARD ;
2393
+ }
2394
+ }
2325
2395
}
2326
2396
phi = phi -> next ;
2327
2397
}
@@ -3825,7 +3895,9 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
3825
3895
&& (trace_buffer -> stop == ZEND_JIT_TRACE_STOP_LOOP
3826
3896
|| trace_buffer -> stop == ZEND_JIT_TRACE_STOP_RECURSIVE_CALL
3827
3897
|| trace_buffer -> stop == ZEND_JIT_TRACE_STOP_RECURSIVE_RET )
3828
- && ssa -> vars [i ].use_chain != -1 ) {
3898
+ && (ssa -> vars [i ].use_chain != -1
3899
+ || (ssa -> vars [i ].phi_use_chain
3900
+ && !(ssa -> var_info [ssa -> vars [i ].phi_use_chain -> ssa_var ].type & MAY_BE_PACKED_GUARD )))) {
3829
3901
if (!zend_jit_packed_guard (& dasm_state , opline , EX_NUM_TO_VAR (i ), info )) {
3830
3902
goto jit_failure ;
3831
3903
}
@@ -5170,12 +5242,12 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
5170
5242
ssa -> var_info [ssa_op -> op1_use ].type &= ~MAY_BE_PACKED_GUARD ;
5171
5243
} else if ((op2_info & (MAY_BE_ANY |MAY_BE_UNDEF )) == MAY_BE_LONG
5172
5244
&& (op1_info & (MAY_BE_ANY |MAY_BE_UNDEF )) == MAY_BE_ARRAY
5173
- && (op1_info & MAY_BE_ARRAY_PACKED )
5174
- && (op1_info & MAY_BE_ARRAY_HASH )
5245
+ && MAY_BE_PACKED (op1_info )
5246
+ && MAY_BE_HASH (op1_info )
5175
5247
&& orig_op1_type != IS_UNKNOWN ) {
5176
5248
op1_info |= MAY_BE_PACKED_GUARD ;
5177
5249
if (orig_op1_type & IS_TRACE_PACKED ) {
5178
- op1_info &= ~MAY_BE_ARRAY_HASH ;
5250
+ op1_info &= ~( MAY_BE_ARRAY_NUMERIC_HASH | MAY_BE_ARRAY_STRING_HASH ) ;
5179
5251
} else {
5180
5252
op1_info &= ~MAY_BE_ARRAY_PACKED ;
5181
5253
}
@@ -5313,12 +5385,12 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
5313
5385
ssa -> var_info [ssa_op -> op1_use ].type &= ~MAY_BE_PACKED_GUARD ;
5314
5386
} else if ((op2_info & (MAY_BE_ANY |MAY_BE_UNDEF )) == MAY_BE_LONG
5315
5387
&& (op1_info & (MAY_BE_ANY |MAY_BE_UNDEF )) == MAY_BE_ARRAY
5316
- && (op1_info & MAY_BE_ARRAY_PACKED )
5317
- && (op1_info & MAY_BE_ARRAY_HASH )
5388
+ && MAY_BE_PACKED (op1_info )
5389
+ && MAY_BE_HASH (op1_info )
5318
5390
&& orig_op1_type != IS_UNKNOWN ) {
5319
5391
op1_info |= MAY_BE_PACKED_GUARD ;
5320
5392
if (orig_op1_type & IS_TRACE_PACKED ) {
5321
- op1_info &= ~MAY_BE_ARRAY_HASH ;
5393
+ op1_info &= ~( MAY_BE_ARRAY_NUMERIC_HASH | MAY_BE_ARRAY_STRING_HASH ) ;
5322
5394
} else {
5323
5395
op1_info &= ~MAY_BE_ARRAY_PACKED ;
5324
5396
}
0 commit comments