83
83
|.define ZREG_TMP3, ZREG_X17
84
84
|.define ZREG_FPTMP, ZREG_V16
85
85
86
- |.define HYBRID_SPAD, # 32 // padding for stack alignment
86
+ |.define HYBRID_SPAD, 32 // padding for stack alignment
87
87
88
88
#define TMP_ZVAL_OFFSET 16
89
89
#define DASM_ALIGNMENT 16
90
90
91
+ typedef enum _sp_adj_kind {
92
+ SP_ADJ_NONE,
93
+ SP_ADJ_RET,
94
+ SP_ADJ_VM,
95
+ SP_ADJ_JIT,
96
+ SP_ADJ_ASSIGN,
97
+ SP_ADJ_LAST
98
+ } sp_adj_kind;
99
+
100
+ static int sp_adj[SP_ADJ_LAST];
101
+
91
102
/* Encoding of immediate. TODO: shift mode may be supported in the near future. */
92
103
#define MAX_IMM12 0xfff // maximum value for imm12
93
104
#define MAX_IMM16 0xffff // maximum value for imm16
@@ -196,13 +207,13 @@ static int logical_immediate_p (uint64_t value, uint32_t reg_size)
196
207
197
208
|.macro ADD_HYBRID_SPAD
198
209
||#ifndef ZEND_VM_HYBRID_JIT_RED_ZONE_SIZE
199
- | add sp, sp, HYBRID_SPAD
210
+ | add sp, sp, # HYBRID_SPAD
200
211
||#endif
201
212
|.endmacro
202
213
203
214
|.macro SUB_HYBRID_SPAD
204
215
||#ifndef ZEND_VM_HYBRID_JIT_RED_ZONE_SIZE
205
- | sub sp, sp, HYBRID_SPAD
216
+ | sub sp, sp, # HYBRID_SPAD
206
217
||#endif
207
218
|.endmacro
208
219
@@ -2592,42 +2603,42 @@ static int zend_jit_assign_cv_stub(dasm_State **Dst)
2592
2603
}
2593
2604
2594
2605
static const zend_jit_stub zend_jit_stubs[] = {
2595
- JIT_STUB(interrupt_handler),
2596
- JIT_STUB(exception_handler),
2597
- JIT_STUB(exception_handler_undef),
2598
- JIT_STUB(leave_function),
2599
- JIT_STUB(leave_throw),
2600
- JIT_STUB(icall_throw),
2601
- JIT_STUB(throw_cannot_pass_by_ref),
2602
- JIT_STUB(undefined_offset),
2603
- JIT_STUB(undefined_index),
2604
- JIT_STUB(cannot_add_element),
2605
- JIT_STUB(undefined_offset_ex),
2606
- JIT_STUB(undefined_index_ex),
2607
- JIT_STUB(cannot_add_element_ex),
2608
- JIT_STUB(undefined_function),
2609
- JIT_STUB(negative_shift),
2610
- JIT_STUB(mod_by_zero),
2611
- JIT_STUB(invalid_this),
2612
- JIT_STUB(trace_halt),
2613
- JIT_STUB(trace_exit),
2614
- JIT_STUB(trace_escape),
2615
- JIT_STUB(hybrid_runtime_jit),
2616
- JIT_STUB(hybrid_profile_jit),
2617
- JIT_STUB(hybrid_hot_code),
2618
- JIT_STUB(hybrid_func_hot_counter),
2619
- JIT_STUB(hybrid_loop_hot_counter),
2620
- JIT_STUB(hybrid_hot_trace),
2621
- JIT_STUB(hybrid_func_trace_counter),
2622
- JIT_STUB(hybrid_ret_trace_counter),
2623
- JIT_STUB(hybrid_loop_trace_counter),
2624
- JIT_STUB(assign_const),
2625
- JIT_STUB(assign_tmp),
2626
- JIT_STUB(assign_var),
2627
- JIT_STUB(assign_cv_noref),
2628
- JIT_STUB(assign_cv),
2606
+ JIT_STUB(interrupt_handler, SP_ADJ_JIT, SP_ADJ_NONE ),
2607
+ JIT_STUB(exception_handler, SP_ADJ_JIT, SP_ADJ_NONE ),
2608
+ JIT_STUB(exception_handler_undef, SP_ADJ_JIT, SP_ADJ_NONE ),
2609
+ JIT_STUB(leave_function, SP_ADJ_JIT, SP_ADJ_NONE ),
2610
+ JIT_STUB(leave_throw, SP_ADJ_JIT, SP_ADJ_NONE ),
2611
+ JIT_STUB(icall_throw, SP_ADJ_JIT, SP_ADJ_NONE ),
2612
+ JIT_STUB(throw_cannot_pass_by_ref, SP_ADJ_JIT, SP_ADJ_NONE ),
2613
+ JIT_STUB(undefined_offset, SP_ADJ_JIT, SP_ADJ_NONE ),
2614
+ JIT_STUB(undefined_index, SP_ADJ_JIT, SP_ADJ_NONE ),
2615
+ JIT_STUB(cannot_add_element, SP_ADJ_JIT, SP_ADJ_NONE ),
2616
+ JIT_STUB(undefined_offset_ex, SP_ADJ_JIT, SP_ADJ_NONE ),
2617
+ JIT_STUB(undefined_index_ex, SP_ADJ_JIT, SP_ADJ_NONE ),
2618
+ JIT_STUB(cannot_add_element_ex, SP_ADJ_JIT, SP_ADJ_NONE ),
2619
+ JIT_STUB(undefined_function, SP_ADJ_JIT, SP_ADJ_NONE ),
2620
+ JIT_STUB(negative_shift, SP_ADJ_JIT, SP_ADJ_NONE ),
2621
+ JIT_STUB(mod_by_zero, SP_ADJ_JIT, SP_ADJ_NONE ),
2622
+ JIT_STUB(invalid_this, SP_ADJ_JIT, SP_ADJ_NONE ),
2623
+ JIT_STUB(trace_halt, SP_ADJ_JIT, SP_ADJ_NONE ),
2624
+ JIT_STUB(trace_exit, SP_ADJ_JIT, SP_ADJ_NONE ),
2625
+ JIT_STUB(trace_escape, SP_ADJ_JIT, SP_ADJ_NONE ),
2626
+ JIT_STUB(hybrid_runtime_jit, SP_ADJ_VM, SP_ADJ_NONE ),
2627
+ JIT_STUB(hybrid_profile_jit, SP_ADJ_VM, SP_ADJ_NONE ),
2628
+ JIT_STUB(hybrid_hot_code, SP_ADJ_VM, SP_ADJ_NONE ),
2629
+ JIT_STUB(hybrid_func_hot_counter, SP_ADJ_VM, SP_ADJ_NONE ),
2630
+ JIT_STUB(hybrid_loop_hot_counter, SP_ADJ_VM, SP_ADJ_NONE ),
2631
+ JIT_STUB(hybrid_hot_trace, SP_ADJ_VM, SP_ADJ_NONE ),
2632
+ JIT_STUB(hybrid_func_trace_counter, SP_ADJ_VM, SP_ADJ_NONE ),
2633
+ JIT_STUB(hybrid_ret_trace_counter, SP_ADJ_VM, SP_ADJ_NONE ),
2634
+ JIT_STUB(hybrid_loop_trace_counter, SP_ADJ_VM, SP_ADJ_NONE ),
2635
+ JIT_STUB(assign_const, SP_ADJ_RET, SP_ADJ_ASSIGN ),
2636
+ JIT_STUB(assign_tmp, SP_ADJ_RET, SP_ADJ_ASSIGN ),
2637
+ JIT_STUB(assign_var, SP_ADJ_RET, SP_ADJ_ASSIGN ),
2638
+ JIT_STUB(assign_cv_noref, SP_ADJ_RET, SP_ADJ_ASSIGN ),
2639
+ JIT_STUB(assign_cv, SP_ADJ_RET, SP_ADJ_ASSIGN ),
2629
2640
#ifdef CONTEXT_THREADED_JIT
2630
- JIT_STUB(context_threaded_call),
2641
+ JIT_STUB(context_threaded_call, SP_ADJ_NONE, SP_ADJ_NONE ),
2631
2642
#endif
2632
2643
};
2633
2644
@@ -2637,6 +2648,66 @@ extern char *_tls_start;
2637
2648
extern char *_tls_end;
2638
2649
#endif
2639
2650
2651
+ #ifdef HAVE_GDB
2652
+ # if 0
2653
+ typedef struct _Unwind_Context _Unwind_Context;
2654
+ typedef int (*_Unwind_Trace_Fn)(_Unwind_Context *, void *);
2655
+ extern int _Unwind_Backtrace(_Unwind_Trace_Fn, void *);
2656
+ extern uintptr_t _Unwind_GetCFA(_Unwind_Context *);
2657
+
2658
+ typedef struct _zend_jit_unwind_arg {
2659
+ int cnt;
2660
+ uintptr_t cfa[3];
2661
+ } zend_jit_unwind_arg;
2662
+
2663
+ static int zend_jit_unwind_cb(_Unwind_Context *ctx, void *a)
2664
+ {
2665
+ zend_jit_unwind_arg *arg = (zend_jit_unwind_arg*)a;
2666
+ arg->cfa[arg->cnt] = _Unwind_GetCFA(ctx);
2667
+ arg->cnt++;
2668
+ if (arg->cnt == 3) {
2669
+ return 5; // _URC_END_OF_STACK
2670
+ }
2671
+ return 0; // _URC_NO_REASON;
2672
+ }
2673
+
2674
+ static void ZEND_FASTCALL zend_jit_touch_vm_stack_data(void *vm_stack_data)
2675
+ {
2676
+ zend_jit_unwind_arg arg;
2677
+
2678
+ memset(&arg, 0, sizeof(arg));
2679
+ _Unwind_Backtrace(zend_jit_unwind_cb, &arg);
2680
+ if (arg.cnt == 3) {
2681
+ sp_adj[SP_ADJ_VM] = arg.cfa[2] - arg.cfa[1];
2682
+ }
2683
+ }
2684
+ # else
2685
+ static void ZEND_FASTCALL zend_jit_touch_vm_stack_data(void *vm_stack_data)
2686
+ {
2687
+ uintptr_t ret;
2688
+
2689
+ __asm__ (
2690
+ "ldr %0, [x29]\n\t"
2691
+ "sub %0 ,%0, x29"
2692
+ : "=r"(ret));
2693
+
2694
+ sp_adj[SP_ADJ_VM] = ret;
2695
+ }
2696
+ # endif
2697
+
2698
+ extern void (ZEND_FASTCALL *zend_touch_vm_stack_data)(void *vm_stack_data);
2699
+
2700
+ static zend_never_inline void zend_jit_set_sp_adj_vm(void)
2701
+ {
2702
+ void (ZEND_FASTCALL *orig_zend_touch_vm_stack_data)(void *);
2703
+
2704
+ orig_zend_touch_vm_stack_data = zend_touch_vm_stack_data;
2705
+ zend_touch_vm_stack_data = zend_jit_touch_vm_stack_data;
2706
+ execute_ex(NULL); // set sp_adj[SP_ADJ_VM]
2707
+ zend_touch_vm_stack_data = orig_zend_touch_vm_stack_data;
2708
+ }
2709
+ #endif
2710
+
2640
2711
static int zend_jit_setup(void)
2641
2712
{
2642
2713
allowed_opt_flags = 0;
@@ -2753,6 +2824,24 @@ static int zend_jit_setup(void)
2753
2824
# endif
2754
2825
#endif
2755
2826
2827
+ memset(sp_adj, 0, sizeof(sp_adj));
2828
+ #ifdef HAVE_GDB
2829
+ sp_adj[SP_ADJ_RET] = 0;
2830
+ sp_adj[SP_ADJ_ASSIGN] = 32;
2831
+ if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) {
2832
+ zend_jit_set_sp_adj_vm(); // set sp_adj[SP_ADJ_VM]
2833
+ #ifndef ZEND_VM_HYBRID_JIT_RED_ZONE_SIZE
2834
+ || sp_adj[SP_ADJ_JIT] = sp_adj[SP_ADJ_VM] + HYBRID_SPAD; // sub r4, HYBRID_SPAD
2835
+ #else
2836
+ || sp_adj[SP_ADJ_JIT] = sp_adj[SP_ADJ_VM];
2837
+ #endif
2838
+ } else if (GCC_GLOBAL_REGS) {
2839
+ || sp_adj[SP_ADJ_JIT] = sp_adj[SP_ADJ_RET] + SPAD; // sub r4, SPAD
2840
+ } else {
2841
+ || sp_adj[SP_ADJ_JIT] = sp_adj[SP_ADJ_RET] + NR_SPAD; // sub r4, NR_SPAD
2842
+ }
2843
+ #endif
2844
+
2756
2845
return SUCCESS;
2757
2846
}
2758
2847
@@ -2780,8 +2869,10 @@ static int zend_jit_prologue(dasm_State **Dst)
2780
2869
| SUB_HYBRID_SPAD
2781
2870
} else if (GCC_GLOBAL_REGS) {
2782
2871
| stp x29, x30, [sp, # -SPAD]! // stack alignment
2872
+ |// mov x29, sp
2783
2873
} else {
2784
2874
| stp x29, x30, [sp, # -NR_SPAD]! // stack alignment
2875
+ |// mov x29, sp
2785
2876
| stp FP, RX, T2 // save FP and IP
2786
2877
| mov FP, FCARG1x
2787
2878
}
0 commit comments