@@ -1340,11 +1340,12 @@ static void* dasm_labels[zend_lb_MAX];
1340
1340
1341
1341
|.macro SET_EX_OPLINE, op, tmp_reg
1342
1342
|| if (op == last_valid_opline) {
1343
+ || zend_jit_use_last_valid_opline();
1343
1344
| SAVE_IP
1344
1345
|| } else {
1345
1346
| ADDR_OP2_2 mov, aword EX->opline, op, tmp_reg
1346
1347
|| if (!GCC_GLOBAL_REGS) {
1347
- || last_valid_opline = NULL ;
1348
+ || zend_jit_reset_last_valid_opline() ;
1348
1349
|| }
1349
1350
|| }
1350
1351
|.endmacro
@@ -1578,6 +1579,7 @@ static void* dasm_labels[zend_lb_MAX];
1578
1579
1579
1580
|.macro UNDEFINED_OFFSET, opline
1580
1581
|| if (opline == last_valid_opline) {
1582
+ || zend_jit_use_last_valid_opline();
1581
1583
| call ->undefined_offset_ex
1582
1584
|| } else {
1583
1585
| SET_EX_OPLINE opline, r0
@@ -1587,6 +1589,7 @@ static void* dasm_labels[zend_lb_MAX];
1587
1589
1588
1590
|.macro UNDEFINED_INDEX, opline
1589
1591
|| if (opline == last_valid_opline) {
1592
+ || zend_jit_use_last_valid_opline();
1590
1593
| call ->undefined_index_ex
1591
1594
|| } else {
1592
1595
| SET_EX_OPLINE opline, r0
@@ -1596,38 +1599,64 @@ static void* dasm_labels[zend_lb_MAX];
1596
1599
1597
1600
|.macro CANNOT_ADD_ELEMENT, opline
1598
1601
|| if (opline == last_valid_opline) {
1602
+ || zend_jit_use_last_valid_opline();
1599
1603
| call ->cannot_add_element_ex
1600
1604
|| } else {
1601
1605
| SET_EX_OPLINE opline, r0
1602
1606
| call ->cannot_add_element
1603
1607
|| }
1604
1608
|.endmacro
1605
1609
1606
- static zend_bool reuse_ip;
1607
- static zend_bool delayed_call_chain;
1608
- static uint32_t delayed_call_level;
1609
- static const zend_op *last_valid_opline;
1610
- static int jit_return_label;
1611
- static uint32_t current_trace_num;
1610
+ static zend_bool reuse_ip = 0;
1611
+ static zend_bool delayed_call_chain = 0;
1612
+ static uint32_t delayed_call_level = 0;
1613
+ static const zend_op *last_valid_opline = NULL;
1614
+ static zend_bool use_last_vald_opline = 0;
1615
+ static zend_bool track_last_valid_opline = 0;
1616
+ static int jit_return_label = -1;
1617
+ static uint32_t current_trace_num = 0;
1618
+
1619
+ static void zend_jit_track_last_valid_opline(void)
1620
+ {
1621
+ use_last_vald_opline = 0;
1622
+ track_last_valid_opline = 1;
1623
+ }
1624
+
1625
+ static void zend_jit_use_last_valid_opline(void)
1626
+ {
1627
+ if (track_last_valid_opline) {
1628
+ use_last_vald_opline = 1;
1629
+ track_last_valid_opline = 0;
1630
+ }
1631
+ }
1632
+
1633
+ static zend_bool zend_jit_trace_uses_initial_ip(void)
1634
+ {
1635
+ return use_last_vald_opline;
1636
+ }
1612
1637
1613
1638
static void zend_jit_set_last_valid_opline(const zend_op *target_opline)
1614
1639
{
1615
1640
if (!reuse_ip) {
1641
+ track_last_valid_opline = 0;
1616
1642
last_valid_opline = target_opline;
1617
1643
}
1618
1644
}
1619
1645
1620
1646
static void zend_jit_reset_last_valid_opline(void)
1621
1647
{
1648
+ track_last_valid_opline = 0;
1622
1649
last_valid_opline = NULL;
1623
1650
}
1624
1651
1625
- static void zend_jit_start_reuse_ip(void) {
1626
- last_valid_opline = NULL;
1652
+ static void zend_jit_start_reuse_ip(void)
1653
+ {
1654
+ zend_jit_reset_last_valid_opline();
1627
1655
reuse_ip = 1;
1628
1656
}
1629
1657
1630
- static void zend_jit_stop_reuse_ip(void) {
1658
+ static void zend_jit_stop_reuse_ip(void)
1659
+ {
1631
1660
reuse_ip = 0;
1632
1661
}
1633
1662
@@ -2804,6 +2833,8 @@ static int zend_jit_align_func(dasm_State **Dst)
2804
2833
reuse_ip = 0;
2805
2834
delayed_call_chain = 0;
2806
2835
last_valid_opline = NULL;
2836
+ use_last_vald_opline = 0;
2837
+ track_last_valid_opline = 0;
2807
2838
jit_return_label = -1;
2808
2839
|.align 16
2809
2840
return 1;
@@ -2849,16 +2880,15 @@ static int zend_jit_save_call_chain(dasm_State **Dst, uint32_t call_level)
2849
2880
2850
2881
static int zend_jit_set_ip(dasm_State **Dst, const zend_op *opline)
2851
2882
{
2852
- if (!last_valid_opline) {
2883
+ if (last_valid_opline == opline) {
2884
+ zend_jit_use_last_valid_opline();
2885
+ } else if (GCC_GLOBAL_REGS && last_valid_opline) {
2886
+ zend_jit_use_last_valid_opline();
2887
+ | ADD_IP (opline - last_valid_opline) * sizeof(zend_op);
2888
+ } else {
2853
2889
| LOAD_IP_ADDR opline
2854
- } else if (last_valid_opline != opline) {
2855
- if (GCC_GLOBAL_REGS) {
2856
- | ADD_IP (opline - last_valid_opline) * sizeof(zend_op);
2857
- } else {
2858
- | LOAD_IP_ADDR opline
2859
- }
2860
2890
}
2861
- last_valid_opline = opline;
2891
+ zend_jit_set_last_valid_opline( opline) ;
2862
2892
2863
2893
return 1;
2864
2894
}
@@ -2890,6 +2920,7 @@ static int zend_jit_check_timeout(dasm_State **Dst, const zend_op *opline, const
2890
2920
if (exit_addr) {
2891
2921
| jne &exit_addr
2892
2922
} else if (last_valid_opline == opline) {
2923
+ || zend_jit_use_last_valid_opline();
2893
2924
| jne ->interrupt_handler
2894
2925
} else {
2895
2926
| jne >1
@@ -3154,7 +3185,7 @@ static int zend_jit_link_side_trace(const void *code, size_t size, uint32_t jmp_
3154
3185
return zend_jit_patch(code, size, jmp_table_size, zend_jit_trace_get_exit_addr(exit_num), addr);
3155
3186
}
3156
3187
3157
- static int zend_jit_trace_link_to_root(dasm_State **Dst, zend_jit_trace_info *t, zend_bool check_interrupt )
3188
+ static int zend_jit_trace_link_to_root(dasm_State **Dst, zend_jit_trace_info *t, const void *timeout_exit_addr )
3158
3189
{
3159
3190
const void *link_addr;
3160
3191
size_t prologue_size;
@@ -3188,11 +3219,11 @@ static int zend_jit_trace_link_to_root(dasm_State **Dst, zend_jit_trace_info *t,
3188
3219
}
3189
3220
link_addr = (const void*)((const char*)t->code_start + prologue_size);
3190
3221
3191
- if (check_interrupt ) {
3222
+ if (timeout_exit_addr ) {
3192
3223
/* Check timeout for links to LOOP */
3193
3224
| MEM_OP2_1_ZTS cmp, byte, executor_globals, vm_interrupt, 0, r0
3194
3225
| je &link_addr
3195
- | jmp ->interrupt_handler
3226
+ | jmp &timeout_exit_addr
3196
3227
} else {
3197
3228
| jmp &link_addr
3198
3229
}
0 commit comments